mongodb 怎么用id数组in查询
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongodb 怎么用id数组in查询相关的知识,希望对你有一定的参考价值。
参考技术A > db.dataset.insert('name':'jack')WriteResult( "nInserted" : 1 )
> db.dataset.insert('name':'bob')
WriteResult( "nInserted" : 1 )
> db.dataset.insert('name':'mongos')
WriteResult( "nInserted" : 1 )
> db.dataset.insert('name':'jany')
WriteResult( "nInserted" : 1 )
> db.dataset.find()
"_id" : ObjectId("57822b88ce921d841832de72"), "name" : "testName"
"_id" : ObjectId("579089efad691b26bd57701a"), "name" : "jack"
"_id" : ObjectId("579089f7ad691b26bd57701b"), "name" : "bob"
"_id" : ObjectId("579089fcad691b26bd57701c"), "name" : "mongos"
"_id" : ObjectId("57908a03ad691b26bd57701d"), "name" : "jany"
> db.dataset.find('name':'$in':['bob', 'jack'])
"_id" : ObjectId("579089efad691b26bd57701a"), "name" : "jack"
"_id" : ObjectId("579089f7ad691b26bd57701b"), "name" : "bob"
> db.dataset.find('_id':'$in':[ObjectId('57822b88ce921d841832de72'), ObjectId('579089efad691b26bd57701a')])
"_id" : ObjectId("57822b88ce921d841832de72"), "name" : "testName"
"_id" : ObjectId("579089efad691b26bd57701a"), "name" : "jack"
>
上面是具体的例子,这是in查询的代码例子:
db.dataset.find('name':'$in':['bob', 'jack'])
db.dataset.find('_id':'$in':[ObjectId('57822b88ce921d841832de72'), ObjectId('579089efad691b26bd57701a')])
innodb_log_buffer_size = 8M #事物日志缓存
innodb_log_file_size = 500M #事物日志大小
对 MongoDB $in 查询的响应顺序? [复制]
【中文标题】对 MongoDB $in 查询的响应顺序? [复制]【英文标题】:Order of responses to MongoDB $in query? [duplicate] 【发布时间】:2011-03-09 16:58:54 【问题描述】:$in 条件运算符上的 MongoDB 文档没有说明任何关于顺序的内容。如果我运行表单查询
db.things.find('_id': '$in': id_array);
返回结果的顺序是什么?有没有办法告诉 MongoDB “我希望对结果进行排序,以便它们与 id_array
中的 id 的顺序相同?”
【问题讨论】:
2.6 的任何解决方案? 简单的 Python/PyMongo 解决方案:***.com/a/40048951/304209 检查this 答案。 【参考方案1】:在JIRA 上请求此功能:
很快就得到了很好的回应:用$or
代替$in
c.find( _id: $in:[ 1, 2, 0 ] ).toArray()
对比
c.find( $or:[ _id:1 , _id:2 , _id:0 ] ).toArray()
阅读错误报告了解更多信息。
更新:
$or work-around hack 从 2.6.x 开始不再有效 - 这是实现的副作用,具有 changed。
【讨论】:
当您以编程方式生成列表时并不那么容易/好,但有一个解决方案很好。 此方法似乎不适用于 2.6.x,如 JIRA 评论中所述【参考方案2】:如果您不介意使用 Underscore.js 并且不太担心规模(IE,您不介意 fetch
-ing 而不是使用光标),以下是我维持秩序的方式:
var results = db.things.find('_id': '$in': id_array).fetch();
return _.sortBy(results, function(thing)
return id_array.indexOf(thing._id);
);
【讨论】:
我在这里看到了一个权衡:这种方法看起来更干净,但它可能会使用更多的 CPU。发生这种情况是因为 array.indexOf 将为您的结果数组中的每个项目扫描 id_array ,并且在完成所有这些工作之后,它会结束对所有结果的处理。自己检查一下:jsfiddle.net/davidrc/gyjrtovu 当然这对前端来说不是问题(我们正在谈论一些毫秒),但是当我们在后端运行此代码时,可能会增加额外的负载。 同意。我必须为 【参考方案3】:@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] );
【讨论】:
不错的改进!谢谢。【参考方案4】:我遇到了同样的问题,我的解决方案是创建一个哈希映射来在我的 id 数组(我的查询)和我的 MongoDB 结果数组之间进行映射。
额外的工作是浏览结果数组并为每个项目插入一个新的键值对:键是 ID,值是结果对象。
然后,当我想以与查询相同的顺序浏览结果时,我可以使用哈希图来检索正确的对象。没有排序,也没有花哨的 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
【讨论】:
我也做了同样的事情:) 如果数据很大,你不能在内存中这样做。 @JyotmanSingh - 你能理解“非常大”是什么意思吗?我需要这个功能,所以想知道它是否是一个有效的解决方案。谢谢。 @user1063287 如果您的目标是按顺序获得结果,您可以查看此解决方案:***.com/questions/22797768/…【参考方案5】:$or 解决方法在 2.6.x 中不再有效,请参阅 https://jira.mongodb.org/browse/SERVER-14083。这是一个 Ruby 解决方法实现:https://gist.github.com/dblock/d5ed835f0147467a6a27
【讨论】:
这有点令人失望。【参考方案6】:没有提及结果的顺序,因为它们不会以任何可靠的方式排序。让它们排序的唯一方法是在客户端对 $in 数组中的每个项目进行单独的查询
【讨论】:
好的,这就是我的预期。假设我通过 PyMongo 进行查询。然后我可以: 1. 为 id_array 中的每个 id 创建一个单独的 MongoDB 并将其附加到列表的末尾(由于查询过多而效率低下),或者 2. 进行我的问题中给出的单个 MongoDB 查询,然后使用 Python将结果从 MongoDB 复制到正确排序的列表中(效率低下,因为我在客户端复制潜在的大量数据)?没有更好的办法吗?我可以在 MongoDB 上运行某种自定义查询,在结果返回之前对其进行排序? 你可以改变你的架构。实际上,现在 mongodb-user 列表上有一个问题正在讨论该选项,正是针对这个问题。可能应该检查一下并在那里跟进。 我参加这个聚会可能有点晚了,但我刚刚遇到了这个问题。我的解决方案是构建(在我的情况下)ObjectId
的字典到位置(即,在我用于$in
查询的列表中的位置),然后使用它来重新排列输出。不过,我正在处理少量项目,所以这可能对您的情况没有帮助。
我基本上采用了与@dcrosta 相同的机制:使用原始“列表中”排序作为参考手动重新排序结果。我记得这也是 SQL 数据库的问题,所以不是 Mongo 的特性。以上是关于mongodb 怎么用id数组in查询的主要内容,如果未能解决你的问题,请参考以下文章