在查询中对MongoDB $的响应顺序?
在条件运算符$的MongoDB文档没有提到任何有关顺序。 如果我运行一个查询的forms
db.things.find({'_id': {'$in': id_array}});
返回结果的顺序是什么? 有没有办法让我告诉MongoDB“我想要sorting结果,以便它们与id_array
的id id_array
?”
在JIRA上询问这个function时:
很快得到了一个非常好的回应:使用$or
而不是$in
c.find( { _id:{ $in:[ 1, 2, 0 ] } } ).toArray()
与
c.find( { $or:[ { _id:1 }, { _id:2 }, { _id:0 } ] } ).toArray()
阅读错误报告了解更多信息。
更新 :
$或work-around hack不再以2.6.x开头 – 这是一个已经改变的实现的副作用。
我有同样的问题,我的解决scheme是创build一个哈希映射来做我的数组ids(我的查询)和我的MongoDB结果数组之间的映射。
额外的工作是浏览结果数组,并为每个项插入一个新的键值对:键是ID,值是结果对象。
然后,当我想以与查询相同的顺序浏览我的结果时,我可以使用hashmap来检索正确的对象。 没有sorting,也没有花哨的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 ); }
这将显示:
a b c d
没有提到结果的顺序,因为它们不会以任何可靠的方式进行sorting。 让它们sorting的唯一方法是为$ in数组中的每个项目单独查询客户端
@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] } ); }
$或解决方法不再适用于2.6.x,请参阅https://jira.mongodb.org/browse/SERVER-14083 。 以下是一个Ruby解决方法实现: https : //gist.github.com/dblock/d5ed835f0147467a6a27
如果你不介意使用Underscore.js并且不太在意比例尺(IE,你不介意fetch
而不是使用游标),下面是我维护顺序的方法:
var results = db.things.find({'_id': {'$in': id_array}}).fetch(); return _.sortBy(results, function(thing) { return id_array.indexOf(thing._id); });