17

我有一个查询:

ownUnnamedPages = Entries.find( { author : this.userId, title : {$regex: /^unnamed-/ }}, {sort: { title: 1 }}).fetch()

这将返回以下排序的数组:

[ { 
    title: 'unnamed-1',
    text: '<p>sdaasdasdasd</p>',
    tags: [],
    _id: 'Wkxxpapm8bbiq59ig',
    author: 'AHSwfYgeGmur9oHzu',
    visibility: 'public' },
{ 
    title: 'unnamed-10',
    text: '',
    author: 'AHSwfYgeGmur9oHzu',
    visibility: 'public',
    _id: 'aDSN2XFjQPh9HPu4c' },
{ 
    title: 'unnamed-2',
    text: '<p>kkhjk</p>',
    tags: [],
    _id: 'iM9FMCsyzehQvYGKj',
    author: 'AHSwfYgeGmur9oHzu',
    visibility: 'public' },
{ 
    title: 'unnamed-3',
    text: '',
    tags: [],
    _id: 'zK2w9MEQGnwsm3Cqh',
    author: 'AHSwfYgeGmur9oHzu',
    visibility: 'public' }]

问题是它似乎对第一个数字字符进行排序,所以它认为正确的序列是 1、10、2、3 等......我真正想要的是它对整个数字部分进行排序,这样10 将在最后。

我不希望通过为数字添加其他数字(例如 01 或 001)来执行此操作。

我该怎么做?

4

6 回答 6

20

您可以使用

db.collectionName.find().sort({title: 1}).collation({locale: "en_US", numericOrdering: true})

numericOrdering 标志是布尔值并且是可选的。确定是将数字字符串作为数字还是字符串进行比较的标志。如果为真,则作为数字进行比较;即“10”大于“2”。如果为假,则作为字符串进行比较;即“10”小于“2”。默认为假。

于 2018-11-20T17:16:56.750 回答
17

MongoDB 无法按存储为字符串的数字进行排序。您必须将数字作为整数存储在其自己的字段中,用前导零填充,或者在从数据库返回结果后对结果进行排序。

于 2013-04-21T00:10:40.857 回答
5

如果您 0 填充数字,您将能够以正确的顺序搜索为字符串,所以不要使用 0,1,2,3,4,5,6,7,8,9,10,11... 01,02,03,04,05,06,07,08,09,10,11... 字符串搜索将按顺序返回它们。

于 2014-12-29T23:27:21.900 回答
4

mongo 文档说你可以使用 Collat​​ion 来实现这个目标,因为@Eugene Kaurov 说你可以使用

.collation({locale: "en_US", numericOrdering: true})

这是官方文档: mongo ref

并注意现在接受的答案不正确

于 2020-09-18T10:42:41.960 回答
0

在 mongo 中是不可能的(在 ascii 中排序字符串),但是在从集合中获取所有文档后,您可以使用以下函数进行排序

const sortString = (a, b) => {
  const AA = a.title.split('-');
  const BB = b.title.split('-');

  if (parseInt(AA[1], 10) === parseInt(BB[1], 10)) {
    return 0;
  }
  return (parseInt(AA[1], 10) < parseInt(BB[1], 10)) ? -1 : 1;
};

document.sort(sortString);
于 2018-08-16T08:21:42.173 回答
0

就我而言,我们使用聚合。方法是使用字符串的长度进行排序;仅在文本部分始终相同时才有效(在您的情况下未命名)

db.YourCollection.aggregate([
  {
    $addFields: {
      "TitleSize": { $strLenCP: "$Title" }
    }
  },
  {
    $sort: {
      "TitleIdSize": 1,
      "Title": 1
    }
  }
]);

现在我们使用长度排序,第二次排序将使用内容。

例子:

  • “未命名-2”,标题大小:9
  • “无名 7”,标题大小:9
  • “未命名 30”,标题大小:10
  • “未命名-1”,标题大小:9

第一种排序会将 id 按以下顺序排列:27130。然后第二个排序会将 id 以正确的顺序排列:12730

于 2019-05-10T15:41:46.727 回答