2013-06-25 52 views
32

我已经问这是关于another问题的评论,并且在mongodb用户上也发布了question。到目前为止没有回应,所以我正在求助于另一个问题。MongoDB嵌套数组查询

documentation状态:

如果字段保持的阵列,则在操作员将$选择 文档其字段保存包含指定数组中相匹配的值的至少一个 元素的数组(例如, 等)

我使用:

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中壳:

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。

谢谢!

回答

6

使用嵌套elemMatch来搜索数组中的嵌套级别。

详情here

4

简答:$ in是单值字段,$ all是数组。

首先,db.nested.findOne({'level1.level2.0': 'item00'})不起作用,因为level1.level2.0包含一个数组,并且您试图将其与单个值进行比较。

现在,db.nested.findOne({'level1.level2.0': {'$in': ['item00']}})由于类似的原因不起作用。 $ in用于将字段与单个值(您有一个数组)中的几个值(在查询中指定)进行比较。 $ in的意思是:给我的文档有这个字段,这个值包含在这个数组中。

$ all正在工作,因为它说:给我这个字段有几个值的文档,并且该数组的所有值(在查询中)都包含在该字段中。 (编辑)

可能很难获得,但看什么文件说每个:

$所有选择其中领域持有阵列的文件,包含了所有元素(e.g. <value>, <value1>, etc.)在阵列。

$在选择其中字段值指定数组e.g. <value1>, <value2>, etc.

希望它可以帮助

+0

感谢您花时间回复,但不幸的是,您的答案都不正确。在手册的“Read”页面中,搜索“以下操作将光标返回到bios集合中的所有文档,其中数组字段contribs包含元素'UNIX':”在我的问题顶部附近的文档链接中,你可以看到$ in应该在包含数组的字段上工作。最后,您的语句“$ all正在工作,因为...”是错误的:字段中的所有值都不需要存在于查询中,但查询中的所有值都必须存在于文档的字段中。 – dgorur

+0

感谢您为“$ all正在工作,因为......”中的更正。所以你在说$ in应该适用于数组,而且文档是这样说的。现在我很感兴趣。我会做一些实验,看看我是否知道。你在这里有一个非常有趣的问题! – AntonioOtero

+0

我把我的发现放在另一个答案中,我希望它对你有用。 – AntonioOtero

29

运行一些查询后在等于任何价值的文件,我得出的结论是$ in不适用于数组阵列

您可以使用$elemMatch来代替它,但它会工作,但令人沮丧的是MongoDB的文档没有警告它。

我创建这个文件:

{ 
     "_id": "51cb12857124a215940cf2d4", 
     "level1": [ 
     [ 
      "item00", 
      "item01" 
     ], 
     [ 
      "item10", 
      "item11" 
     ] 
     ], 
     "items": [ 
     "item20", 
     "item21" 
     ] 
} 

注意的领域“项目”是一个字符串数组,这个查询工作完美:

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

呵呵。现在你说。我对某些查询使用了这种解决方法,但是:如果我想使用$ nin,该怎么办?同样的神秘行为出现了,然后我们开始怀疑我们得到的所有查询结果。另外,感谢“阵列数组”术语。 – dgorur