我已经对此进行了一段时间的战斗,但似乎无法弄清楚如何执行理论上应该是一个非常简单的查询...
我需要检索(或更确切地说,排除)包含数组的文档,其中两个值都出现在数组中的精确索引处,但是没有一个值出现在该精确索引处。我已经尝试过$ and运算符来实现这一点,但是我没有得到我期望的结果。
数组也可以大于2个值。
我已经尝试了以下代码,但是省略了在确切位置包含任一值的所有文档,而不仅是两个。
$and: [{"value.0": {$ne: 'X'}}, {"value.1": {$ne: 'X'}}]
我期望:
[X,X]
被排除在外
[Y,X]
被包括
[X,Y]
被包括
是的,这有点棘手,但是您的意思是$or
。
拿下您的文件:
{ "value" : [ "X", "X" ] }
{ "value" : [ "X", "X", "A" ] }
{ "value" : [ "Y", "X" ] }
{ "value" : [ "X", "Y" ] }
{ "value" : [ "B", "Y" ] }
db.collection.find({
"$or": [
{ "value.0": { "$ne": "X" } },
{ "value.1": { "$ne": "X" } }
]
})
返回三个文档:
{ "value" : [ "Y", "X" ] }
{ "value" : [ "X", "Y" ] }
{ "value" : [ "B", "Y" ] }
这是因为其中任何一个条件都需要完成,即"X"
不必是这些位置中任何一个元素的值。当您的逻辑是“这个或那个”时,您实际上是在说$or
。
请注意,不要将这与$nor
哪个谓词都不应该“完全匹配”的语句混淆:
db.collection.find({
"$nor": [
{ "value.0": "X" },
{ "value.1": "X" }
]
})
将返回:
{ "value" : [ "B", "Y" ] }
这两个位置值都不包含"X"
。
基本上可以归结为区分之间或者和没有在您需要办理什么
如果您实际上要确保的是“第一个位置”必须在其中一个元素中包含“ X”,那么您基本上需要一个计算表达式来“切片”添加到查询末尾的数组内容逻辑:
无论是从3.6 MongoDB的现代及以上的使用$expr
和$slice
db.collection.find({
"$or": [
{ "value.0": { "$ne": "X" } },
{ "value.1": { "$ne": "X" } }
],
"$expr": {
"$in": [ "X", { "$slice": [ "$value", 0, 2 ] }]
}
})
或通过$where
旧版本:
db.collection.find({
"$or": [
{ "value.0": { "$ne": "X" } },
{ "value.1": { "$ne": "X" } }
],
"$where": function() {
return this.value.slice(0,2).indexOf("X") != -1
}
})
两者都只会返回"X"
所有存在的地方:
{ "value" : [ "Y", "X" ] }
{ "value" : [ "X", "Y" ] }
不能使用常规查询运算符来表达用于查看“数组切片”中要存在的值的附加逻辑。因此,使用附加语句是为了丢弃那些位置处带有“ X”的所有内容。
请注意,从技术上讲,所有表达式都是必需的,但是这种计算表达式需要进行集合扫描,而常规的不等式运算实际上不需要。
因此,如果这是您的意图,最好将两者结合起来。
同样,“技术上”只需匹配"X"
“可能”就足够了:
db.collection.find({
"value": "X",
"$or": [
{ "value.0": { "$ne": "X" } },
{ "value.1": { "$ne": "X" } }
]
})
但这不能保证该值出现在前两个位置。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句