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')])

参考技术B innodb_flush_log_at_trx_commit = 1 #每次commit 日志缓存中的数据刷到磁盘中
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查询的主要内容,如果未能解决你的问题,请参考以下文章

使用 $in 查询在 mongodb 中更新?

用PHP查询mongo数据时,条件是某个字段(A为数组)不为空,但是有的记录中并没有字段A,这个条件怎么写?

mongodb安装.

mongoDB 安装

匹配 MongoDB 中嵌套子文档的嵌套数组

获取数组中每个索引的子文档元素计数并更新子文档键 - 数组中的子文档(IN MONGODB)