查询中对MongoDB $的响应顺序?

Tre*_*ham 48 mongodb

关于$ in条件运算符的MongoDB文档没有说明任何关于顺序的内容.如果我运行表单的查询

db.things.find({'_id': {'$in': id_array}});
Run Code Online (Sandbox Code Playgroud)

返回结果的顺序是什么?有没有办法告诉MongoDB"我希望结果排序,以便它们与ids的顺序相同id_array?"

Jon*_*Ong 11

JIRA上被问到这个功能:

迅速得到了很好的回应:使用$or而不是$in

c.find( { _id:{ $in:[ 1, 2, 0 ] } } ).toArray()
Run Code Online (Sandbox Code Playgroud)

c.find( { $or:[ { _id:1 }, { _id:2 }, { _id:0 } ] } ).toArray()
Run Code Online (Sandbox Code Playgroud)

阅读错误报告以获取更多信息.

更新:

从2.6.x开始,$或work-hack不再起作用 - 这是实现的副作用已经改变.

  • 如JIRA评论中所述,此方法似乎不适用于2.6.x. (7认同)

Jas*_*son 6

我有同样的问题,我的解决方案是创建一个哈希映射来执行我的数组(我的查询)和我的MongoDB结果数组之间的映射.

额外的工作是浏览结果数组并为每个项插入一个新的键值对:键是ID,值是结果对象.

然后,当我想以与查询相同的顺序浏览我的结果时,我可以使用hashmap来检索正确的对象.没有排序,也没有花哨的Mongo DB选项.

在Javascript中它将是这样的:

//The order you want
var queryIds = [ 8, 5, 3, 7 ];

//The results from MongoDB in an undefined order
var resultsFromMongoDB = [
    {_id: 7, data: "d" },
    {_id: 8, data: "a" },
    {_id: 5, data: "b" },
    {_id: 3, data: "c" },
];

//The function to create a hashmap to do the mapping
function createHashOfResults( results ){
    var hash = {};

    for( var i = 0 ; i < results.length ; i++ ){
        var item = results[i];
        var id = item._id;
        hash[ id ] = item;
    }

    return hash;
}

//Let's build the hashmap
var hash = createHashOfResults( resultsFromMongoDB );

//Now we can display the results in the order we want
for( var i = 0 ; i < queryIds.length ; i++ ){
    var queryId = queryIds[i];
    var result = hash[queryId];
    console.log( result.data );
}
Run Code Online (Sandbox Code Playgroud)

这将显示:

a
b
c
d
Run Code Online (Sandbox Code Playgroud)

  • 如果数据非常大,则无法在内存中执行此操作。 (2认同)

Dav*_*ruz 6

@Jason的回答是正确的.

关于其他答案:我不建议逐个查询,因为它可能带来严重的性能问题.

除了@Jason的回答,它还可以使用Array.reduce和Array.map方法进行优化,如下所示:

//The order you want
var queryIds = [8, 5, 3, 7];

//The results from MongoDB in an undefined order
var resultsFromMongoDB = [
    {_id: 7, data: "d"},
    {_id: 8, data: "a"},
    {_id: 5, data: "b"},
    {_id: 3, data: "c"}
];

var reorderedResults = naturalOrderResults(resultsFromMongoDB, queryIds);


function naturalOrderResults(resultsFromMongoDB, queryIds) {
    //Let's build the hashmap
    var hashOfResults = resultsFromMongoDB.reduce(function (prev, curr) {
        prev[curr._id] = curr;
        return prev;
    }, {});

    return queryIds.map( function(id) { return hashOfResults[id] } );
}
Run Code Online (Sandbox Code Playgroud)


mdi*_*olf 4

未提及结果的顺序,因为它们不会以任何可靠的方式排序。让它们排序的唯一方法是在客户端对 $in 数组中的每个项目进行单独的查询

  • 我参加这个聚会可能有点晚了,但我刚刚遇到了这个问题。我的解决方案是构建一个(在我的例子中)“ObjectId”的字典来定位(即,我用于“$in”查询的列表中的位置),然后使用它来重新排列输出。不过,我正在处理少量项目,所以这可能对您的情况没有帮助。 (3认同)