0

让我直截了当地提出这个问题,好的,我有类似的文档结构

让集合名称为样本;

如果我不知道 someIdAsString。

{
_id : ObjectId("someObjectId"),
test : {
    someIdAsString : {
        field1 : value1,
        field2 : value2
    },
            someOtherIdAsString : {}
            .....
            .....
            And so on
  }
}

我有 field1 和 field2 值如何使用此信息查询集合。

field1 & field2 将在运行时知道让我们说它是 field1 = '33' & field2 = '3333' 和文档之类的

{
_id : ObjectId("522182515f8wea670900001b"),
test : {
    522182515f8c4wd70900001b : {
    field1 : '33',
    field2 : '3333'
    },
        522182515f8cea670900001b : {}
        .....
        .....
        And so on
   }
}

谢谢

4

1 回答 1

1

我建议您更改架构,使此文someIdAsString本成为值而不是键,从而使对象test成为对象列表。如果你知道每一个键,你可以试试

db.sample.find({$or: [
    {"test.someIdAsString.field1": value1,
     "test.someIdAsString.field2": value2},
    {"test.someOtherIdAsString.field1": value1,
     "test.someOtherIdAsString.field2": value2},
    ...
]})

对于您所有的“someIdAsString”可能性。

如果将结构更改为:

{
    _id : ObjectId("someObjectId"),
    test : [
        {
            _id : someIdAsString,
            field1 : value1,
            field2 : value2
        },
        {
            _id : someOtherIdAsString,
            field1 : value3,
            field2 : value4
        },
        ...
    ]
}

您可以将查询更改为:

db.sample.find({
    "test.field1": value1,
    "test.field2": value2
})

在不知道嵌入键名的情况下使用查询同时仍然使用数据结构的解决方法是$where 运算符中的 JavaScript 。

db.sample.find(function(){
    var ttk;
    var tt = this.test;
    for(key in tt){
        ttk = tt[key]
        if(ttk.field1 === value1 && ttk.field2 === value2){
            return true;
        }
    }
    return false;
})
于 2013-08-31T06:54:34.240 回答