在一个集合中,我存储了一些数据,这些数据是针对在别处生成的移动设备UID进行映射的。例如:
{
devices: {
'b2e4fe52d4ab57fd55fa': { model: 'aPhone', number: 1111111 },
'b2e4fe52d4ab57fd55fb': { model: 'bPhone', number: 2222222 },
'b2e4fe52d4ab57fd55fc': { model: 'cPhone', number: 3333333 }
}
}
有没有办法在不使用UID的情况下检索代表一个设备的对象?
对于一个只在模型或数字上使用$ elemMatch的数组来说这很容易,但似乎它的使用仅限于数组,是否有文档的模拟运算符?
答案 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;
}})