我已将此问题作为对another问题的评论,并在mongodb-user上发布了question。到目前为止没有回复,所以我要求另外提问。
如果该字段包含数组,则$ in运算符选择 其字段包含至少包含一个数组的文档 与指定数组中的值匹配的元素(例如, 等等。)
我正在使用:
mongod --version:
db version v2.2.2, pdfile version 4.5
Thu May 30 12:19:12 git version: d1b43b61a5308c4ad0679d34b262c5af9d664267
mongo --version:
MongoDB shell version: 2.0.4
在MongoDB shell中:
db.nested.insert({'level1': {'level2': [['item00', 'item01'], ['item10', 'item11']]}})
以下是根据文档应该运行的查询列表及其产生的结果:
为什么这不起作用?
> db.nested.findOne({'level1.level2.0': 'item00'})
null
为什么我需要$ all?
> db.nested.findOne({'level1.level2.0': {'$all': ['item00']}})
{
"_id" : ObjectId("51a7a4c0909dfd8872f52ed7"),
"level1" : {
"level2" : [
[
"item00",
"item01"
],
[
"item10",
"item11"
]
]
}
}
下列中至少有一项应该可以使用,对吧?
> db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})
null
> db.nested.findOne({'level1.level2': {'$in': ['item00']}})
null
有什么想法吗?如果查询语法不像宣传的那样工作,我们正在考虑放弃MongoDB。
谢谢!
答案 0 :(得分:39)
在运行一些查询后,我得出的结论是 $ in不适用于数组数组。
你可以使用$elemMatch
代替它,但是令人沮丧的是MongoDB的文档没有提出警告。
我创建了这个文档:
{
"_id": "51cb12857124a215940cf2d4",
"level1": [
[
"item00",
"item01"
],
[
"item10",
"item11"
]
],
"items": [
"item20",
"item21"
]
}
请注意,字段“items”是一个字符串数组,此查询完美运行:
db.nested.findOne({"items":{"$in":["item20"]} })
现在,“level1.0”也是一个字符串数组,唯一的区别是它在另一个数组中。此查询应该有效但不是:
db.nested.findOne({"level1.0":{"$in":["item00"]} })
获得结果的唯一方法是使用$ elemMatch:
db.nested.findOne({"level1":{"$elemMatch":{"$in":['item00']}} })
所以$elemMatch
解决了这个问题,但真正的解决方案是将MongoDB的文档更新为$in
对数组数组不起作用的状态。也许您应该向10gen提交请求。
答案 1 :(得分:8)
使用嵌套的elemMatch
来搜索数组中的嵌套级别。
答案 2 :(得分:4)
简短回答:$ in表示单值字段,$ all表示数组。
首先,db.nested.findOne({'level1.level2.0': 'item00'})
不起作用,因为level1.level2.0包含一个数组,并且您尝试将其与单个值进行比较。
现在,由于类似的原因,db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})
无效。 $ in用于将字段与单个值(您有一个数组)与数组中的多个值(在查询中指定)进行比较。
$ in说:给我这个字段的文档,该值包含在这个数组中。
$ all正在工作,因为它说:给我这个字段有几个值的文档,这个数组的所有值(在查询中)都包含在该字段中。 (编辑)的
可能很难得到,但请看文档中为每个文档所说的内容:
$ all选择数组该字段包含数组且包含所有元素
(e.g. <value>, <value1>, etc.
)的文档。$ in选择字段值等于指定数组中任何值的文档(
e.g. <value1>, <value2>, etc.
)
希望有所帮助