对于“给定路径”中的数据实际上是否在数组中,MongoDB基本上不在乎。如果你想的区别,那么你需要“告诉它”:
db.stuff.find({ "a": "x", "$where": "return !Array.isArray(this.a)" })
这是$where
增加了讨价还价,在那里你可以提供明确提出了一个条件:“这是一个数组”通过Array.isArray()
在JavaScript评估中。而JavaScript NOT !
声明颠倒了逻辑。
另一种方法是添加$exists
检查:
db.stuff.find({ "a": "x", "a.0": { "$exists": false } })
其中也基本上问“这是一个数组”通过寻找该第一元素索引。所以“反向”false
大小写意味着“这不是一个数组”。
或者即使你注意,您可以使用$elemMatch
只选择阵列,但“否定”,使用$not
:
db.stuff.find({ "a": { "$not": { "$elemMatch": { "$eq": "x" } } } })
虽然可能“而不是”最好的选择,因为这也是“否定索引的使用“,其他例子都通过至少包括”一个“匹配的积极条件来努力避免。因此,它是最好的,包括了“隐AND”组合参数:
db.stuff.find({
"a": { "$eq": "x", "$not": { "$elemMatch": { "$eq": "x" } } }
})
或为“聚合”不支持$where
,您可以测试使用$isArray
汇聚运营商应该将MongoDB的版本(3.2或更高版本)支持它:
db.stuff.aggregate([
{ "$match": { "a": "x" } },
{ "$redact": {
"$cond": {
"if": { "$not": { "$isArray": "$a" } },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
注意到在任何可能的情况下以及在任何情况下都提供“常规”查询条件是一种很好的做法。
还注意到查询BSON $type
通常不会在这种情况下工作,因为该数组本身的“内容”其实都是“字符串”,这是什么$type
操作是要考虑的,并因此不报告这样的数组实际上是一个数组。
谢谢!我认为应该在可能的情况下使用'a.0'的答案,因为它会使用索引(如果存在),而'$ where'不能。而且,'return'关键字没用。 – stenci
@stenci这不是“无用的”,它只是“$ where”认为它是“隐含的”,但“良好的语言习惯”(我习惯于这样做)实际上表明你“应该”实际上总是返回'从任何功能。请注意,即使在这种形式下,'function()'也基本上是“隐含的”。 –