Mongodb - 将嵌套文档与未知密钥匹配

时间:2014-11-28 00:36:29

标签: mongodb

在一个集合中,我存储了一些数据,这些数据是针对在别处生成的移动设备UID进行映射的。例如:

{
    devices: {
        'b2e4fe52d4ab57fd55fa': { model: 'aPhone', number: 1111111 },
        'b2e4fe52d4ab57fd55fb': { model: 'bPhone', number: 2222222 },
        'b2e4fe52d4ab57fd55fc': { model: 'cPhone', number: 3333333 }
    }
}

有没有办法在不使用UID的情况下检索代表一个设备的对象?

对于一个只在模型或数字上使用$ elemMatch的数组来说这很容易,但似乎它的使用仅限于数组,是否有文档的模拟运算符?

2 个答案:

答案 0 :(得分:3)

  

是否存在Documents

的模拟运算符

没有。没有运算符可以匹配和投影文档中的单个键值对,没有知道键。

您必须编写代码才能对每个设备文档进行后期处理,如下所示:

var devices = db.devices.findOne().devices; 
    var keys = Object.keys(devices);
    for(var i=0;i<keys.length;i++){
    var device = devices[keys[i]];
    if(device.model == 'aPhone' && device.number == 1111111)
    {
        print(keys[i]);
        // do the processing here
        break;
    }
}

如果您有一个选项可以更改您的架构,如下所示,这更灵活,看起来在逻辑上也是正确的,

db.devices.insert({
    devices: [
        {"id":"b2e4fe52d4ab57fd55fa",  model: 'aPhone', number: 1111111 },
        {"id":"b2e4fe52d4ab57fd55fb",  model: 'bPhone', number: 2222222 },
        {"id":"b2e4fe52d4ab57fd55fc",  model: 'cPhone', number: 3333333 }
    ]
})

然后,您可以通过简单的查找和项目查询来实现它。

db.devices.findOne({"devices.model":"aPhone",
                    "devices.number":1111111},
                   {"devices.$":1})

答案 1 :(得分:-1)

如果由于性能而导致数据量很大,请使用$where,但不建议使用{。}。

db.collection.find(
{ $where: function() {
  var input = { model: 'aPhone', number: 1111111 };  
  if(this.devices != undefined){  
  for(var key in this.devices){
    d = this.devices[key];
    if (d.model==input.model && d.number==input.number) return true;
    }
  }
  return false;
}})