英文:
mongoDB count deeply nested elements on more then one condition
问题
请帮忙,我需要找到具有以下条件之一的所有_a[]._p[]元素的count():
-
_a[]._p[].s.d.t[].dateP=2022 并且 _a[]._p[].s.d.t[].tF="N"
-
_a[]._p[].s.c.t[].dateP=2022 并且 _a[]._p[].s.c.t[].tF="N"
在以下类型的文档中:
{
"_id": ObjectId("5c05984246a0201286d4b57a"),
"f": "x",
"_a": [
{
"_p": [
{
"pid": 2,
"s": {
"d": {
"t": [
{
"id": 1,
"dateP": "20200-09-20"
},
{
"id": 2,
"dateP": "2022-09-20",
"tF": "N"
}
]
},
"c": {
"t": [
{
"id": 3,
"dateP": "20300-09-22"
},
{
"id": 4,
"dateP": "2022-09-23",
"tF": "N"
}
]
}
}
}
]
}
]
}
在我的尝试中,我只能计算部分匹配条件的文档,但不确定在有更多嵌套数组的情况下是否正确,并不确定如何更快地计算_a内的_p元素:
db.collection.count({ "_a._p.s.c.t": { $elemMatch: { tF: "N", dateP: /^2022/i } } })
从Playground中预期的结果应如下所示:
{ total: 1 }
因为_a._p具有与上述条件匹配的s.d.t的id:2和s.c.t的id:4。
英文:
Please, help , I need to find count() of all _a[]._p[] elements having at least one of:
_a[]._p[].s.d.t[].dateP=2022 and _a[]._p[].s.d.t[].tF="N"
and
_a[]._p[].s.c.t[].dateP=2022 and _a[]._p[].s.c.t[].tF="N"
in following type of document:
{
"_id": ObjectId("5c05984246a0201286d4b57a"),
f: "x",
"_a": [
{
"_p": [
{
"pid": 2,
"s": {
"d": {
"t": [
{
id: 1,
"dateP": "20200-09-20",
},
{
id: 2,
"dateP": "2022-09-20",
"tF": "N"
}
]
},
"c": {
"t": [
{
id: 3,
"dateP": "20300-09-22"
},
{
id: 4,
"dateP": "2022-09-23",
"tF": "N"
}
]
}
}
}
]
}
]
}
In my attempt I can count only the documents that partially match the condition , but not sure if this is correct when there is more nested arrays and not sure how to do it faster and count the _p elements inside the _a:
db.collection.count({ "_a._p.s.c.t":{ $elemMatch:{ tF:"N" , dateP: /^2022/i } } })
The expected result from playground need to look as follow:
{ total: 1 }
Since the _a._p having s.d.t with id:2 and s.c.t with id:4 match the above condition
答案1
得分: 1
更新:仅计算元素
db.collection.aggregate([
{
$project: {
sct: {
"$size": "$_a._p.s.c.t"
},
scd: {
"$size": "$_a._p.s.d.t"
}
}
},
])
<details>
<summary>英文:</summary>
and the solution should be like:
_update: only count element_
db.collection.aggregate([
{
$project: {
sct: {
"$size": "$_a._p.s.c.t"
},
scd: {
"$size": "$_a._p.s.d.t"
}
}
},
])
[MONGO_PALYGROUND](https://mongoplayground.net/p/P8wVsZlIfPD)
</details>
# 答案2
**得分**: 1
这是一个方法,可以在不使用`$unwind`的情况下执行,尽管`$reduce`的嵌套级别似乎非常容易出错。我希望在依赖它之前,你能用大量数据测试它。
```mongodb
db.collection.aggregate([
{
"$match": {
"_a._p.s.d.t": {
"$elemMatch": {
"dateP": {"$regex": "^2022"},
"tF": "N"
}
},
"_a._p.s.c.t": {
"$elemMatch": {
"dateP": {"$regex": "^2022"},
"tF": "N"
}
}
}
},
{
"$project": {
"ap": "$_a._p"
}
},
{
"$project": {
"docCount": {
"$reduce": {
"input": "$ap",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{
"$reduce": {
"input": "$$this",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{
"$cond": [
{
"$and": [
{
"$reduce": {
"input": "$$this.s.c.t",
"initialValue": false,
"in": {
"$or": [
"$$value",
{
"$and": [
{"$eq": ["$$this.tF", "N"]},
{
"$regexMatch": {
"input": "$$this.dateP",
"regex": "^2022"
}
}
]
}
]
}
}
},
{
"$reduce": {
"input": "$$this.s.d.t",
"initialValue": false,
"in": {
"$or": [
"$$value",
{
"$and": [
{"$eq": ["$$this.tF", "N"]},
{
"$regexMatch": {
"input": "$$this.dateP",
"regex": "^2022"
}
}
]
}
]
}
}
}
]
},
1,
0
]
}
]
}
}
}
]
}
}
}
}
},
{
"$group": {
"_id": null,
"totalCount": {"$sum": "$docCount"}
}
}
])
在mongoplayground.net上尝试它。
英文:
Here's one way you can do it without "$unwind"
, although the "$reduce"
nesting levels seem very error prone. I hope you test this with lots of data before depending on it.
db.collection.aggregate([
{
"$match": {
"_a._p.s.d.t": {
"$elemMatch": {
"dateP": {"$regex": "^2022"},
"tF": "N"
}
},
"_a._p.s.c.t": {
"$elemMatch": {
"dateP": {"$regex": "^2022"},
"tF": "N"
}
}
}
},
{
"$project": {
"ap": "$_a._p"
}
},
{
"$project": {
"docCount": {
"$reduce": {
"input": "$ap",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{
"$reduce": {
"input": "$$this",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{
"$cond": [
{
"$and": [
{
"$reduce": {
"input": "$$this.s.c.t",
"initialValue": false,
"in": {
"$or": [
"$$value",
{
"$and": [
{"$eq": ["$$this.tF", "N"]},
{
"$regexMatch": {
"input": "$$this.dateP",
"regex": "^2022"
}
}
]
}
]
}
}
},
{
"$reduce": {
"input": "$$this.s.d.t",
"initialValue": false,
"in": {
"$or": [
"$$value",
{
"$and": [
{"$eq": ["$$this.tF", "N"]},
{
"$regexMatch": {
"input": "$$this.dateP",
"regex": "^2022"
}
}
]
}
]
}
}
}
]
},
1,
0
]
}
]
}
}
}
]
}
}
}
}
},
{
"$group": {
"_id": null,
"totalCount": {"$sum": "$docCount"}
}
}
])
Try it [mongoplayground.net](https://mongoplayground.net/p/L760LSbMdZU "Click me!").
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论