Mongodb:如何按照数组元素的顺序对“选择”进行排序

6

我正在执行这个mongo查询:

db.mytable.find({id:{$in:["1","2", "3", "4" ]}});

它以一种奇怪的顺序返回所有结果,如下所示:
4,3,2,1

我需要按照查询数组中定义的顺序检索所有结果。
1,2,3,4

有可能吗?

1
这是编程,所有与代码相关的事情都是可能的。只是可能需要时间。 - jcolebrand
不可能让MongoDB按照指定的顺序返回结果。 :) - Asya Kamsky
3个回答

2

虽然查询结果的顺序无法保证,但您可以在结果返回后进行排序。以下是两个示例,第一个按照您想要的顺序排序,第二个按相反顺序排序。

const arr = ["1", "2", "3", "4" ];

db.collection.find({ id: { $in: arr }})  
  .then(result => {
    
    let sorted = arr.map(i => result.find(j => j.id === i));
    console.log(sorted) // 1, 2, 3, 4

    let reversed = arr.reverse().map(i => result.find(j => j.id === i));
    console.log(reversed) // 4, 3, 2, 1
    
});

如果你想进行真正的 MongoDB ID 查找,请使用 db.collection.find({ _id: { $in: arr }}).map(i => result.find(j => j._id == i))(注意两个等号而不是三个)


现在如何在聚合查询本身中执行它? - justin.m.chase

1

你可以像这样编写查询:

db.mytable.find({id:{$in:["1","2", "3", "4" ]}}).sort({id:1})

如果您想按照id ASC的顺序返回结果:

来源:MongoDB高级查询

但是,如果您只想根据$in数组对结果进行排序,请尝试以相反的顺序对$in数组进行排序,与$in数组的第一个元素相关的结果可能会出现在结果的最后一个元素。


我的数组列表没有定义顺序,它的值可能是字母数字混合的...那么,恐怕无法实现 :( - larrytron
@larrytron 如果它没有定义的顺序,只需反转它的顺序,你不需要知道顺序是如何的,例如你可以在PHP中使用array_reverse - YAAK
抱歉,我不明白你的想法。想象一下另一个例子:db.mytable.find({id:{$in:["foo","bar", "baz", "qux" ]}}); 然后我需要按照这里的顺序(foo,bar,baz,qux)精确地检索这些值,但我得到的是类似于 qux,bar,foo,baz 的东西.. 我的意思是完全不同的。希望这有助于澄清。谢谢。 - larrytron
好的,对于那个,我想没有办法。 - YAAK
1
没有办法在不处理两次数组的情况下实现 OP 想要的功能。您可以使用 JS 按照指定顺序进行排序,就像您可以在任何其他语言中编写一样。但是作为库的本地扩展这样做并不合理。 - jcolebrand
有没有人能推荐一个快速的排序算法?还要在Node.js中使用? - larrytron

1

需要注意以下几点:

1.) MongoDB和大多数数据库一样,如果您不使用sort()调用,就不能保证查询结果的顺序。如果您确实想要保证查询结果按照特定的顺序返回,那么您需要指定具体的排序顺序。

2.) 通常情况下,最近更新/移动的文档将显示在结果集的末尾,但仍然不能保证。MongoDB使用“自然顺序”对对象进行本地排序,虽然这非常接近插入顺序,但不能保证完全相同。

3.) 索引字段的行为会有所不同。值得指出的是,看起来您的查询正在使用id而不是_id。前者_id默认情况下会被索引,而id除非您已经明确地向该字段添加了索引,否则不会被索引。

您可以在此处阅读有关MongoDB排序和排序的更多信息: http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接