如何编写比较嵌入式文档的Mongodb查询?

时间:2014-02-17 19:29:43

标签: mongodb mongomapper

考虑一个Order文档,其中包含许多LineItems嵌入文档和一个SpecialLineItem嵌入文档。

要查找具有给定类型的LineItem的订单,这可以:

find({ 'lineItems.type' : 'food' })

如何找到至少有一个LineItem类型 与SpecialLineItem类型相同的订单?

此外,某些订单没有LineItems。

例如,找到这个文件:

lineItems: { type:food },
           { type:wood }
specialLineItem: { type: food }

但不是:

lineItems: { type:food }
specialLineItem: { type: food }

lineItems: []
specialLineItem: { type: food }

2 个答案:

答案 0 :(得分:1)

  

如何查找至少有一个LineItem类型与SpecialLineItem类型不同的订单?

这不太可能。插入或更新文档时,您必须存储该信息。

但是,您可以使用$where operator或只是传递javascript方法。但是,这非常慢,因为它必须执行完整的集合扫描:

db.coll.find(function() { for(var i = 0; i < this.lineItems.length; i++){ 
  if(this.lineItems[i].type != this.specialLineItem.type) {
        return true; } 
  } 
  return false;
}).pretty();

答案 1 :(得分:1)

正如我在评论中建议的那样,我建议添加一个字段,在文档保存/更新时更新以反映此查询的答案。索引,回答这个问题会非常快。

以下是map-reduce代码的一个简单示例,该代码将提供匹配文档_id的集合以及匹配的特殊订单项:

map = function() {
    var items = this.lineitems || [];
    var match = this.specialLineItem.type;
    for(var i = 0, l = items.length; i < l; i++) {
        if (match === items[i].type) {
            emit(this._id, match);
            return;
        }
    }
};

reduce = function(key, values) {
   return values;  
};

使用:

db.test.mapReduce(map, reduce, { out: 'test2' })

结果如下:

{ "_id" : ObjectId("530276101378b009f17ff653"), "value" : "food" }
{ "_id" : ObjectId("530276341378b009f17ff656"), "value" : "food" }