英文:
Find records where at least one fulfills a condition
问题
我想查找Mongo中的一些记录,它们都满足某个条件,并且至少有一个满足第二个独立条件。
示例:
假设记录具有 counter
和 isHandled
参数(分别为 Number
和 Boolean
)。我想查找所有 counter >= 100
的记录,并且至少有一个满足第一个条件的记录也具有 isHandled
设置为 false
。
假设我有以下记录:
[
{
"_id": "1",
"counter": 50,
"isHandled": false
},
{
"_id": "2",
"counter": 50,
"isHandled": true
},
{
"_id": "3",
"counter": 100,
"isHandled": true
},
{
"_id": "4",
"counter": 100,
"isHandled": true
},
{
"_id": "5",
"counter": 120,
"isHandled": false
},
{
"_id": "6",
"counter": 100,
"isHandled": true
}
]
还有 threshold = 100
。我的查询应该返回 _id
为 "3"
, "4"
, "5"
和 "6"
的记录。但是,如果记录 "5"
不存在,那么不应返回任何记录。原因是因为所有满足第一个条件(counter
)的记录都不满足第二个条件。
我的第一部分可能是 { counter: { $gte: threshold } }
。
有没有办法实现这个?使用一些管道?
英文:
I'm looking to find some records from Mongo where they all fulfill some condition and that at least one of them fulfills a second, separate, condition.
Example:
Say records have counter
& isHandled
parameters (Number
& Boolean
respectfully).
I'd like to find all records where counter >= 100
and that at least one of the records that fulfill the first requirement also has isHandled
set to false
.
Say I have these records:
[
{
"_id": "1",
"counter": 50,
"isHandled": false
},
{
"_id": "2",
"counter": 50,
"isHandled": true
},
{
"_id": "3",
"counter": 100,
"isHandled": true
},
{
"_id": "4",
"counter": 100,
"isHandled": true
},
{
"_id": "5",
"counter": 120,
"isHandled": false
},
{
"_id": "6",
"counter": 100,
"isHandled": true
}
]
And also threshold = 100
. My query should return the records with _id
"3", "4", "5" & "6"
. However, if record "5"
was not there, then no record should be returned. The reason is that since all of the records that satisfy the first condition (counter
), none satisfy the second condition.
My first part might be { counter: { $gte: threshold } }
.
Any idea how I can achieve this? Some sort of pipeline?
答案1
得分: 1
以下是已翻译的内容:
$match
条件:{$gte: threshold},用于筛选计数大于等于阈值的文档。- 使用
$setWindowFields
计算isHandled
字段的$rank
。这里的技巧是,如果所有记录都为真,它们将共享排名:1。如果有一些文档为假,那么假文档将具有排名:1,而真文档将具有排名:2。 - 使用
$match
条件,通过$or
条件筛选所有记录,其中条件是isHandled
为假或rank
为 2(这意味着它们是真实文档,但存在一些假文档使其排名为2)。
英文:
You can do the followings in an aggregation pipeline:
$match
with counter : {$gte: threshold}$setWindowFields
to compute$rank
forisHandled
field. The trick here is if all records are true, they will all share the rank: 1. If some documents are false, the false documents will have rank: 1 and true documents will have rank: 2$match
all records by a$or
condition onisHandled: false
orrank: 2
( that means they are true documents, but there exists some false documents to make it having rank 2)
db.collection.aggregate([
{
"$match": {
counter: {
$gte: 100
}
}
},
{
"$setWindowFields": {
"partitionBy": null,
"sortBy": {
"isHandled": 1
},
"output": {
"rank": {
$denseRank: {}
}
}
}
},
{
$match: {
$expr: {
$or: [
{
$eq: [
"$isHandled",
false
]
},
{
$eq: [
"$rank",
2
]
}
]
}
}
},
{
$unset: "rank"
}
])
EDIT: thanks for @Noel 's comment. Changed to use $denseRank
from $rank
答案2
得分: 0
const threshold = 100;
db.collection.find({
$and: [
{ counter: { $gte: threshold } },
{
$or: [
{ isHandled: false },
{ isHandled: { $exists: false } }
]
}
]
});
英文:
You can try this one:
const threshold = 100;
db.collection.find({
$and: [
{ counter: { $gte: threshold } },
{
$or: [
{ isHandled: false },
{ isHandled: { $exists: false } }
]
}
]
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论