gpt4 book ai didi

node.js - 在 mongodb 中聚合撤消展开

转载 作者:太空宇宙 更新时间:2023-11-04 03:07:07 25 4
gpt4 key购买 nike

我有多个类似这样的数据

{
"_id" : ObjectId("57189fcd72b6e0480ed7a0a9"),
"venueId" : ObjectId("56ce9ead08daba400d14edc9"),
"companyId" : ObjectId("56e7d62ecc0b8fc812b2aac5"),
"cardTypeId" : ObjectId("56cea8acd82cd11004ee67a9"),
"matchData" : [
{
"matchId" : ObjectId("57175c25561d87001e666d12"),
"matchDate" : ISODate("2016-04-08T18:30:00.000Z"),
"matchTime" : "20:00:00",
"_id" : ObjectId("57189fcd72b6e0480ed7a0ab"),
"active" : 3,
"cancelled" : 0,
"produced" : 3
},
{
"matchId" : ObjectId("57175c25561d87001e666d13"),
"matchDate" : ISODate("2016-04-09T18:30:00.000Z"),
"matchTime" : "20:00:00",
"_id" : ObjectId("57189fcd72b6e0480ed7a0aa"),
"active" : null,
"cancelled" : null,
"produced" : null
}
],
"__v" : 0
}

我正在按 companyId 进行分组,并且工作正常,但我想根据 matchtimematchIdmatchData 中进行搜索,为此,我在展开后使用这样的搜索查询$unwind matchData

db.getCollection('matchWiseData').aggregate([
{"$match":{
"matchData.matchId":{"$in":[ObjectId("57175c25561d87001e666d12")]}
}},
{"$unwind":"$matchData"},
{"$match":{
"matchData.matchId":{"$in":[ObjectId("57175c25561d87001e666d12")]}}
}])

它给了我正确的结果,但是在应用展开之后有什么方法可以撤消它,我使用展开只是在子文档中搜索,或者有任何其他方法可以在子文档中搜索。

最佳答案

你当然可以使用 $push$first$group使文档恢复原样:

db.getCollection('matchWiseData').aggregate([
{ "$match":{
"matchData.matchId":{"$in":[ObjectId("57175c25561d87001e666d12")]}
}},
{ "$unwind":"$matchData"},
{ "$match":{
"matchData.matchId":{"$in":[ObjectId("57175c25561d87001e666d12")]}
}},
{ "$group": {
"_id": "$_id",
"venueId": { "$first": "$venueId" },
"companyId": { "$first": "$companyId" },
"cardTypeId": { "$first": "$cardTypeId" },
"matchData": { "$push": "$matchData" }
}}
])

但你可能应该只使用 $filter首先使用 MongoDB 3.2:

db.getCollection('matchWiseData').aggregate([
{ "$match":{
"matchData.matchId":{"$in":[ObjectId("57175c25561d87001e666d12")]}
}},
{ "$project": {
"venueId": 1,
"companyId": 1,
"cardTypeId": 1,
"matchData": {
"$filter": {
"input": "$matchData",
"as": "match",
"cond": {
"$or": [
{ "$eq": [ "$$match.matchId", ObjectId("57175c25561d87001e666d12") ] }
]
}
}
}
}}
])

如果您至少有 MongoDB 2.6,您仍然可以使用 $map$setDifference相反:

db.getCollection('matchWiseData').aggregate([
{ "$match":{
"matchData.matchId":{"$in":[ObjectId("57175c25561d87001e666d12")]}
}},
{ "$project": {
"venueId": 1,
"companyId": 1,
"cardTypeId": 1,
"matchData": {
"$setDifference": [
{ "$map": {
"input": "$matchData",
"as": "match",
"in": {
"$cond": [
{ "$or": [
{ "$eq": [ "$$match.matchId", ObjectId("57175c25561d87001e666d12") ] }
]},
"$$match",
false
]
}
}},
[false]
]
}
}}
])

当每个数组元素都已经有一个“唯一”标识符时,这完全没问题,因此“set”操作只是从 $map 中删除 false 值。

这两种方法都可以从数组中“过滤”内容,而无需实际使用 $unwind

<小时/>

注意:不确定您是否真的理解了 $in用于匹配“条件列表”,而不是要求在数组上匹配。所以一般情况下可以是:

 "matchData.matchId": ObjectId("57175c25561d87001e666d12")

实际上只有一个值可以匹配。当您有条件“列表”时,可以使用 $in$or。数组本身对所需的运算符没有影响。

关于node.js - 在 mongodb 中聚合撤消展开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36786278/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com