为了账号安全,请及时绑定邮箱和手机立即绑定

MongoDB的$in子句保证订单

MongoDB的$in子句保证订单

忽然笑 2019-06-14 16:54:00
MongoDB的$in子句保证订单当使用MongoDB时$in子句,返回的文档的顺序总是与数组参数的顺序相对应吗?
查看完整描述

3 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

使用聚合查询的另一种方法仅适用于MongoDB verion>3.4 -

功劳归功于这个美好的博客帖子.

按此顺序获取的示例文档-

var order = [ "David", "Charlie", "Tess" ];

这个问题-

var query = [
             {$match: {name: {$in: order}}},
             {$addFields: {"__order": {$indexOfArray: [order, "$name" ]}}},
             {$sort: {"__order": 1}}
            ];var result = db.users.aggregate(query);

另一篇文章引用了解释这些聚合运算符的文章-

“$addField”阶段在3.4中是新的,它允许您在不了解所有其他现有字段的情况下对现有文档“$project”新字段。新的“$indexOfArray”表达式返回给定数组中特定元素的位置。

基本上addToSet运算符追加一个新的order字段到每个文档,当它找到它时,order字段表示我们提供的数组的原始顺序。然后,我们简单地根据这个字段对文档进行排序。


查看完整回答
反对 回复 2019-06-14
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

如果你不想用aggregate,另一个解决方案是使用find然后使用array#sort:

如果$in值是与数字类似的原始类型,您可以使用如下方法:

var ids = [4, 2, 8, 1, 9, 3, 5, 6];MyModel.find({ _id: { $in: ids } }).exec(function(err, docs) {
    docs.sort(function(a, b) {
        // Sort docs by the order of their _id values in ids.
        return ids.indexOf(a._id) - ids.indexOf(b._id);
    });});

如果$in值是非原始类型,如ObjectId,则需要另一种方法,如indexOf在这种情况下通过引用进行比较。

如果使用Node.js4.x+,可以使用Array#findIndexObjectID#equals若要通过更改sort职能:

docs.sort((a, b) => ids.findIndex(id => a._id.equals(id)) - 
                    ids.findIndex(id => b._id.equals(id)));

或使用任何Node.js版本,并带有下划线/存档findIndex:

docs.sort(function (a, b) {
    return _.findIndex(ids, function (id) { return a._id.equals(id); }) -
           _.findIndex(ids, function (id) { return b._id.equals(id); });});


查看完整回答
反对 回复 2019-06-14
  • 3 回答
  • 0 关注
  • 1803 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信