考虑以下集合,其中父文档的amount
字段的值为100000
,并且嵌入的文档数组具有相同的字段amount
且值相同。< / p>
{
"_id" : ObjectId("5975ce5f05563b6303924914"),
"amount" : 100000,
"offers" : [
{
"amount": 100000
}
]
}
有没有办法匹配至少有一个嵌入式文档offer
的所有对象与父级相同的数量?
如果我查询这个,它可以正常工作:
find({ offers: { $elemMatch: { loan_amount: 100000 } } })
但是我不知道我正在尝试组装的真实查询中的实际值100000
,我需要使用一个变量作为父文档数量字段。这样的事情。
find({ offers: { $elemMatch: { loan_amount: "parent.loan_amount" } } })
感谢任何建议。我希望通过$eq
或$elemMatch
执行此操作,并避免聚合,但可能无法实现。
谢谢!
答案 0 :(得分:3)
标准查询无法比较&#34;文件中的价值观。这实际上是您使用.aggregate()
和$redact
执行的操作:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
在这里,我们使用$filter
将父文档中"amount"
的值与数组中的值进行比较。如果至少有一个是等于&#34;然后我们"$$KEEP"
该文档,否则我们"$$PRUNE"
在大多数最新版本中,我们可以使用$indexOfArray
来缩短它。
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$ne": [
{ "$indexOfArray": [ "$offers.amount", "$amount" ] },
-1
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
如果你真的只想要&#34;匹配的数组元素&#34;同样,你会在投影中添加$filter
:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$size": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}},
0
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": {
"amount": 1,
"offers": {
"$filter": {
"input": "$offers",
"as": "o",
"cond": { "$eq": [ "$$o.amount", "$amount" ] }
}
}
}}
])
但主要原则当然是&#34;减少&#34;返回仅那些实际符合条件的文件数量为&#34;第一个&#34;优先。否则,你只是在进行不必要的计算和工作,这需要时间和资源,以便你以后放弃的结果。
所以&#34;过滤&#34;首先,&#34;重塑&#34;第二是优先考虑。
答案 1 :(得分:1)
我认为从MongoDB 3.6版开始,您实际上可以使用expr运算符通过简单的过滤器来做到这一点。
遵循这些原则:
find({
$expr: {
$in: [
"$amount",
"$offers.amount"
]
}
})
在mongoplayground.net上查看实时示例