MongoDB:嵌套的$,不工作 问题
假设我们有三个文件:MongoDB:嵌套的$,不工作 问题,mongodb,Mongodb,假设我们有三个文件: [ { row: [ {identifier: 'a', value: 10}, {identifier: 'b', value: 24}, {identifier: 'c', value: 3}, ] }, { row: [ {identifier: 'a', value: 11}, {identifier: 'b', value: 75}, {identifier
[
{
row: [
{identifier: 'a', value: 10},
{identifier: 'b', value: 24},
{identifier: 'c', value: 3},
]
},
{
row: [
{identifier: 'a', value: 11},
{identifier: 'b', value: 75},
{identifier: 'c', value: 4},
]
},
{
row: [
{identifier: 'a', value: 2},
{identifier: 'b', value: 1},
{identifier: 'c', value: 3},
]
}
]
预期结果
如果不满足任何条件,则每行的值应为null
。条件必须包括标识符
。这是我的问题
[
{
row: [
{identifier: 'a', value: null}, // Because it's 'a' and lower than 10
{identifier: 'b', value: null}, // Because 'a' is lower than 10
{identifier: 'c', value: null} // Because 'a' is lower than 10
]
},
{
row: [
{identifier: 'a', value: 11}, // Because it's 'a' and not lower than 10
{identifier: 'b', value: 75}, // Because 'a' or 'c' are not lower than 10, greater than 5
{identifier: 'c', value: 4} // Because it's 'c' and greater than 5
]
},
{
row: [
{identifier: 'a', value: null}, // Because it's 'a' and lower than 10
{identifier: 'b', value: null}, // Because 'a' is lower than 10
{identifier: 'c', value: null} // Because 'a' is lower than 10
]
}
]
方法#1
我以为MongoDB看到了这一点:
(A AND B) AND (C AND D)
它首先计算括号,但事实并非如此
进近#2
当我用$nor
替换它时,MongoDB抛出:
MongoError:无法识别的表达式“$nor”
当我将第一个$和
更改为$或
时,整个查询工作正常,但这不是我期望的结果
更新 一个条件是工作正常:
$eq: [
{
$size: {
$filter: {
input: '$row',
as: 'row',
cond: {
$or: [
{
$and: [
{$eq: ['$$row.identifier', 'a']},
{$gt: ['$$row.value', 10]}
]
}
]
}
}
}
},
0
]
现在所有行的值都变为
null
。如果我添加第二个条件,它将被反转($gt
变为$lt
)。我不明白为什么。您可以使用$addFields
创建临时字段,该字段将表示当前文档是否匹配使用()的所有条件,然后生成预期输出
db.col.aggregate([
{
$addFields: {
matches: {
$allElementsTrue: {
$map: {
input: "$row",
as: "r",
in: {
$switch: {
branches: [
{ case: { $and: [{$eq: ["$$r.identifier", "a"]},{$lte: ["$$r.value", 10] }] },
then: false },
{ case: { $and: [{$eq: ["$$r.identifier", "b"]},{$gte: ["$$r.value", 5] }] },
then: false },
],
default: true
}
}
}
}
}
}
},
{
$project: {
row: {
$map: {
input: "$row",
as: "r",
in: {
$cond: {
if: { $eq: [ "$matches", true ] },
then: "$$r",
else: { identifier: "$$r.identifier", value: null }
}
}
}
}
}
}
])
您可以使用
$addFields
创建临时字段,该字段将表示当前文档是否使用()匹配所有条件,然后生成预期输出
db.col.aggregate([
{
$addFields: {
matches: {
$allElementsTrue: {
$map: {
input: "$row",
as: "r",
in: {
$switch: {
branches: [
{ case: { $and: [{$eq: ["$$r.identifier", "a"]},{$lte: ["$$r.value", 10] }] },
then: false },
{ case: { $and: [{$eq: ["$$r.identifier", "b"]},{$gte: ["$$r.value", 5] }] },
then: false },
],
default: true
}
}
}
}
}
}
},
{
$project: {
row: {
$map: {
input: "$row",
as: "r",
in: {
$cond: {
if: { $eq: [ "$matches", true ] },
then: "$$r",
else: { identifier: "$$r.identifier", value: null }
}
}
}
}
}
}
])
您需要以下标准才能获得预期的输出。您还缺少引用,该引用用于引用在过滤器操作符中作为创建的用户变量
{
"$or":[
{"$and":[
{"$eq":["$$row.identifier","a"]},{"$lte":["$$row.value",10]}
]},
{"$and":[
{"$eq":["$$row.identifier","b"]},{"$lt":["$$row.value",5]}
]}
]
}
您需要以下标准才能获得预期的输出。您还缺少引用,该引用用于引用在过滤器操作符中作为创建的用户变量
{
"$or":[
{"$and":[
{"$eq":["$$row.identifier","a"]},{"$lte":["$$row.value",10]}
]},
{"$and":[
{"$eq":["$$row.identifier","b"]},{"$lt":["$$row.value",5]}
]}
]
}
这里的预期结果是什么?这是更大查询的一部分。我添加了预期的结果。
(A和B)和(C和D)
应该按预期工作。什么不起作用?你能添加与预期输出相对应的输入文档和查询条件吗?@Veeram这很奇怪。当我用或替换顶级$和时,我得到一个结果。有了$和我什么也得不到!我将添加一组示例文档。@Veeram I扩展方法#1。这里的预期结果是什么?它是更大查询的一部分。我添加了预期的结果。(A和B)和(C和D)
应该按预期工作。什么不起作用?你能添加与预期输出相对应的输入文档和查询条件吗?@Veeram这很奇怪。当我用或替换顶级$和时,我得到一个结果。有了$和我什么也得不到!我将添加一组示例文档。@Veeram I扩展方法#1。我猜您的解决方案仅将满足条件的值设置为null
。我需要的是,如果满足任何条件,则所有值都应为null。@Julian现在请尝试,您必须使用$switch和$map来比较数组中的每一项,否则将检查数组中所有项的值<5。我猜您的解决方案只会将满足条件的值设置为null
。我需要的是,如果满足任何条件,则所有值都应为null。@Julian现在试试,您必须使用$switch和$map来比较数组中的每一项,否则,数组中的所有项目都将检查值<5。我只是在示例中遗漏了它们,而不是我的实际代码。因此,我刚刚注意到,在更新的查询中,您使用的是$eq,而不是$gt。这是故意的吗?那可能是你的问题。嵌套的$和
将评估$中提到的所有条件以及它正在执行的操作。因此,对于您已发布的查询条件,所有行的大小都将为0,$eq将计算if块,该块用于将所有文档的所有行设置为null。不,在整个工作日内都有效的内容;)我能够更详细地说明这个问题,这很奇怪:当我使用$lt
而不是$gt
时,它会按预期工作。但我不能同时去工作。其中一个条件总是相反的。必须是一个逻辑错误。因此,当您使用{“$gt”:[“$$row.value”,10]}
&$eq
条件作为$size
时,您会得到什么输出?所有文档中的所有行都设置为空?当我只使用一个条件时,它工作正常。任何第二个条件都会被反转($gt
变为$lt
)。我只是在示例中遗漏了它们,而不是我的实际代码。因此我刚刚注意到在更新的查询中,您使用的是$eq,而不是$gt。这是故意的吗?那可能是你的问题。嵌套的$和
将评估$中提到的所有条件以及它正在执行的操作。因此,对于您已发布的查询条件,所有行的大小都将为0,$eq将计算if块,该块用于将所有文档的所有行设置为null。不,在整个工作日内都有效的内容;)我能够更详细地说明这个问题,这很奇怪:当我使用$lt
而不是$gt
时,它会按预期工作。但我不能同时去工作。其中一个条件总是相反的。必须是一个逻辑错误。因此,当您使用{“$gt”:[“$$row.value”,10]}
&$eq
条件作为$size
时,您会得到什么输出?所有文档中的所有行都设置为空?当我只使用一个条件时,它工作正常。任何第二个条件get被反转($gt
变为$lt
)。