$in
运算符适用于数组。
是否有词典的等价物?
以下代码创建两个测试文档,并在数组文档中查找包含所列值之一的文档,但在子文档中找不到包含相同值的文档。
> use test
> db.stuff.drop()
> db.stuff.insertMany([{lst:['a','b'],dic:{a:1,b:2}},{lst:['a','c'],dic:{a:3,c:4}}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("595bbe8b3b0518bcca4b1530"),
ObjectId("595bbe8b3b0518bcca4b1531")
]
}
> db.stuff.find({lst:{$in:['b','c']}},{_id:0})
{ "lst" : [ "a", "b" ], "dic" : { "a" : 1, "b" : 2 } }
{ "lst" : [ "a", "c" ], "dic" : { "a" : 3, "c" : 4 } }
> db.stuff.find({dic:{$in:['b','c']}},{_id:0})
>
编辑(以回答以下答案)
使用下面答案中建议的列表可以防止我找到所需的元素。例如,在这个问题的上面insertMany
和下面的答案中执行了> x=db.stuff.findOne({lst:{$in:['b','c']}},{_id:0})
{ "lst" : [ "a", "b" ], "dic" : { "a" : 1, "b" : 2 } }
> x
{ "lst" : [ "a", "b" ], "dic" : { "a" : 1, "b" : 2 } }
> x.dic.a
1
> x.dic.b
2
之后,可以用字典来完成,而不是列表(或者我错过了什么?):
eureka.instance.hostname
答案 0 :(得分:4)
对于子文档,没有完全等同于$ in。您可以使用$ exists查询运算符与$或:
结合使用db.stuff.find({$or:[
{'dic.b': {$exists: true}},
{'dic.c': {$exists: true}}
]})
但是,建议的方法是更改架构,以便将键和值更改为{key: "key", value: 123}
子文档的数组:
db.stuff.insertMany([
{dic: [{key: 'a', value: 1}, {key: 'b', value: 2}]},
{dic: [{key: 'a', value: 3}, {key: 'c', value: 4}]}
])
然后您可以使用$ in查找包含某些键的文档:
db.stuff.find({'dic.key': {$in: ['a', 'b']}})
关于这个新架构的特别好处是你可以在$ in查询中使用索引:
db.stuff.createIndex({'dic.key': 1})
如上所述,缺点是像x.dic.a
这样的简单元素访问不再有效。您需要用您的语言进行一些编码。例如。在Javascript:
> var doc = {dic: [{key: 'a', value: 3}, {key: 'c', value: 4}]}
> function getValue(doc, key) {
... return doc.dic.filter(function(elem) {
... return elem.key == key;
... })[0].value;
... }
> getValue(doc, "a")
3
> getValue(doc, "c")
4