有没有办法阻止mongo查询在数组上“分支”?

时间:2015-05-29 21:24:21

标签: mongodb

如果我有以下文件:

{a: {x:1}} // without array
{a: [{x:1}]} // with array

有没有办法查询{'a.x':1}将返回第一个而不是第二个? IE,我想要a.x为1的文档,而a不是数组。

2 个答案:

答案 0 :(得分:5)

请注意future version of MongoDB would incorporate the $isArray aggregation expression。在此期间......

...以下代码可以解决问题,因为$elemMatch运算符只匹配具有数组字段的文档:

import os
import glob

contents = []
json_dir_name = "/path/to/json/dir"

json_pattern = os.path.join(json_dir_name,'*.json'
file_list = glob.glob(json_pattern)
for file in file_list:
  contents.append(read(file))

鉴于该数据集:

> db.test.find({"a.x": 1, "a": {$not: {$elemMatch: {x:1}}}})

它将返回:

> db.test.find({},{_id:0})
{ "a" : { "x" : 1 } }
{ "a" : [ { "x" : 1 } ] }
{ "a" : [ { "x" : 0 }, { "x" : 1 } ] 

请注意,这应被视为短期解决方案。 MongoDB团队非常谨慎地确保> db.test.find({"a.x": 1, "a": {$not: {$elemMatch: {x:1}}}}, {_id:0}) { "a" : { "x" : 1 } } [{x:1}]行为相同(请参阅dot-notation$type for arrays)。因此,考虑在将来的某个时刻,{x:1} 可能会更新(请参阅JIRA问题SERVER-6050)。与此同时,也许值得考虑修复您的数据模型,因此不再需要区分包含一个子文档的数组和一个裸子文档。

答案 1 :(得分:5)

您可以通过添加第二个术语来确保a没有元素。当a是普通子网时,第二项将始终为真,当a为数组时,总是为假(否则第一项将不匹配)。

db.test.find({'a.x': 1, 'a.0': {$exists: false}})