Mongodb 在匹配条件的元素之间聚合$filter

Mongodb 在匹配条件的元素之间聚合$filter,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,数据: 查询是: db.trips.aggregate([ {$match: { "Route.Legs": { $elemMatch: { "StartAddress": "Nittambuwa","Ancestors":{$nin:["Kegalle"]}} }, "Route.Legs.EndAddress":"Kegalle" }}, { $project: { RiderId: "$RiderId",

数据:

查询是:

 db.trips.aggregate([
       {$match: { "Route.Legs": { $elemMatch: { "StartAddress": "Nittambuwa","Ancestors":{$nin:["Kegalle"]}} }, "Route.Legs.EndAddress":"Kegalle" }},
        {  $project: {
             RiderId: "$RiderId",
             Legs: {
                $filter: {
                   input: "$Route.Legs",
                   as: "leg",
                   cond: {
                          "$and": [
                            { "$gte": [ "$$leg.LegId", <**Get the leg id by passing the  start address**> ] },
                            { "$lte": [ "$$leg.LegId", 3 ] }
                          ]
                        }
                }
             }
          }}

    ])
db.trips.aggregate([
{$match:{“Route.Legs”:{$elemMatch:{“StartAddress”:“Nittambuwa”,“祖先”:{$nin:[“Kegalle”]}}},Route.Legs.EndAddress:“Kegalle”},
{$项目:{
RiderId:“$RiderId”,
腿:{
$filter:{
输入:“$Route.Legs”,
如:“腿”,
条件:{
“$and”:[
{“$gte”:[“$$leg.LegId”,]},
{“$lte”:[“$$leg.LegId”,3]}
]
}
}
}
}}
])
基本上,在条件中,我需要查询集合并获取腿ID以进行比较。我尝试了$where,但它无法识别条件中的操作员


这也是为什么我不能在cond中使用$where,$nin的原因。通常,您需要在查找匹配数组项并匹配条件的外部中嵌套另一个条件来应用该条件。然后应用并实际提供条件的
“LegId”
值:

db.trips.aggregate([
  { "$match": { 
    "Route.Legs": { 
      "$elemMatch": { 
        "StartAddress": "Nittambuwa",
        "Ancestors":{ "$nin": [ "Kegalle" ] }
      }
    }, 
    "Route.Legs.EndAddress":"Kegalle" 
  }},
  { "$project": {
    "RiderId": 1,
    "Legs": {
      "$filter": {
        "input": "$Route.Legs",
        "as": "l",
        "cond": {
          "$and": [    
            { "$gte": [
              "$$l.LegId",
              { "$arrayElemAt": [
                { "$map": {
                  "input": { 
                    "$filter": {
                      "input": "$Route.Legs",
                      "as": "l",
                      "cond": {
                        "$and": [
                          { "$eq": [ "$$l.StartAddress", "Nittambuwa" ] },
                          { "$eq": [
                            { "$size": {
                              "$setIntersection": [ [ "Kegalle" ], "$$l.Ancestors" ]
                            }},
                            0
                          ]}
                        ]
                      }
                    }
                  },
                  "as": "l",
                  "in": "$$l.LegId"
                }},
                0
              ]}
            ]},
            { "$lte": [ "$$l.LegId", 3 ] }  
          ]
        }
      }
    }
  }}
])
由于匹配数组元素需要“多个条件”,因此无法真正应用此处这样的内容来获取数组索引

虽然对于聚合条件没有“直接”等价于“逻辑运算符”,但您可以使用替代方法。我在这里应用,因为比较两个“唯一”数组可能是最好的方法。逻辑表明,当“交叉点”的值为
0
时,不存在匹配。因此,符合与之相同的标准

当然,“多个”条件都由包装,因为它就是这样做的

当然,结果会过滤匹配条件的
“LegId”
值和提供的“end”值(即
3
)之间的数组项:

/* 1 */
{
    "_id" : ObjectId("597c48d222b29fc421e82d20"),
    "RiderId" : "DEMO",
    "Legs" : [ 
        {
            "LegId" : 1.0,
            "Distance" : 18008.0,
            "Duration" : 1850.0,
            "Price" : "480",
            "StartAddress" : "Nittambuwa",
            "StartLocation" : [ 
                7.1420863, 
                80.1038061
            ],
            "EndAddress" : "Warakapola",
            "EndLocation" : [ 
                7.2268383, 
                80.1959644
            ],
            "Ancestors" : [ 
                "Colombo"
            ]
        }, 
        {
            "LegId" : 2.0,
            "Distance" : 22478.0,
            "Duration" : 2208.0,
            "Price" : "720",
            "StartAddress" : "Warakapola",
            "StartLocation" : [ 
                7.2268383, 
                80.1959644
            ],
            "EndAddress" : "Kegalle",
            "EndLocation" : [ 
                7.2514362, 
                80.3466076
            ],
            "Ancestors" : [ 
                "Colombo", 
                "Nittambuwa"
            ]
        }
    ]
}

从提供的数据和此处发布的语句的结果中复制和粘贴的所有数据。

通常需要在查找匹配数组项并匹配条件的外部中嵌套另一个,以应用该条件。然后应用并实际提供条件的
“LegId”
值:

db.trips.aggregate([
  { "$match": { 
    "Route.Legs": { 
      "$elemMatch": { 
        "StartAddress": "Nittambuwa",
        "Ancestors":{ "$nin": [ "Kegalle" ] }
      }
    }, 
    "Route.Legs.EndAddress":"Kegalle" 
  }},
  { "$project": {
    "RiderId": 1,
    "Legs": {
      "$filter": {
        "input": "$Route.Legs",
        "as": "l",
        "cond": {
          "$and": [    
            { "$gte": [
              "$$l.LegId",
              { "$arrayElemAt": [
                { "$map": {
                  "input": { 
                    "$filter": {
                      "input": "$Route.Legs",
                      "as": "l",
                      "cond": {
                        "$and": [
                          { "$eq": [ "$$l.StartAddress", "Nittambuwa" ] },
                          { "$eq": [
                            { "$size": {
                              "$setIntersection": [ [ "Kegalle" ], "$$l.Ancestors" ]
                            }},
                            0
                          ]}
                        ]
                      }
                    }
                  },
                  "as": "l",
                  "in": "$$l.LegId"
                }},
                0
              ]}
            ]},
            { "$lte": [ "$$l.LegId", 3 ] }  
          ]
        }
      }
    }
  }}
])
由于匹配数组元素需要“多个条件”,因此无法真正应用此处这样的内容来获取数组索引

虽然对于聚合条件没有“直接”等价于“逻辑运算符”,但您可以使用替代方法。我在这里应用,因为比较两个“唯一”数组可能是最好的方法。逻辑表明,当“交叉点”的值为
0
时,不存在匹配。因此,符合与之相同的标准

当然,“多个”条件都由包装,因为它就是这样做的

当然,结果会过滤匹配条件的
“LegId”
值和提供的“end”值(即
3
)之间的数组项:

/* 1 */
{
    "_id" : ObjectId("597c48d222b29fc421e82d20"),
    "RiderId" : "DEMO",
    "Legs" : [ 
        {
            "LegId" : 1.0,
            "Distance" : 18008.0,
            "Duration" : 1850.0,
            "Price" : "480",
            "StartAddress" : "Nittambuwa",
            "StartLocation" : [ 
                7.1420863, 
                80.1038061
            ],
            "EndAddress" : "Warakapola",
            "EndLocation" : [ 
                7.2268383, 
                80.1959644
            ],
            "Ancestors" : [ 
                "Colombo"
            ]
        }, 
        {
            "LegId" : 2.0,
            "Distance" : 22478.0,
            "Duration" : 2208.0,
            "Price" : "720",
            "StartAddress" : "Warakapola",
            "StartLocation" : [ 
                7.2268383, 
                80.1959644
            ],
            "EndAddress" : "Kegalle",
            "EndLocation" : [ 
                7.2514362, 
                80.3466076
            ],
            "Ancestors" : [ 
                "Colombo", 
                "Nittambuwa"
            ]
        }
    ]
}

所有数据都是从这里提供的数据和发布的声明结果中复制和粘贴的。

任何-1的原因。这个问题愚蠢吗?可能是因为在提出问题时,您实际上没有提供任何数据,而且即使现在您有了与发布的聚合表达式不匹配的格式。也有记录,你不能使用它的原因应该很明显(不是你应该首先考虑它)。如果希望得到一些帮助,那么需要提供与正在运行的表达式实际相关的数据。或者至少“尝试”跑步。@NeilLunn对不起我的不好。我想把数据控制在最低限度,但发布了错误的代码。我已经更新了数据。对此有什么建议吗?只要相同的字段和结构是相关的,你只需要包含那些查询实际处理的字段和结构,就可以将其最小化。说到这里,您最近一次编辑似乎意味着所提供的文档实际上并不符合查询的“条件”。或者至少是因为缺少而发布的查询。事实上,这就是为什么你们会收到反对票,这也是我试图向你们解释的。请注意,否则人们会相应地对待你。@NeilLunn我的错又来了:(…已验证并更新:公司原因-1.问题是否愚蠢?可能是因为在提出问题时,您实际上没有提供任何数据,而且即使现在您已经发布了与聚合表达式不匹配的格式。这也是有记录的,您无法使用它的原因应该非常明显(不是你应该首先考虑它)如果你希望得到一些帮助,那么你需要提供与你正在运行的表达式相关的数据。至少要运行。@NeilLunn抱歉,我的不好。我想把数据保持在最小值,但发布了错误的代码。我已经更新了数据。对此有什么建议吗?保持最小值没什么错,只要相同的字段和相关结构,您只需要包括查询实际处理的字段和结构。说到这里,您最近一次编辑似乎是表示提供的文档实际上不符合“标准”不管怎么说,都是查询的结果。或者至少是发布的查询,因为它也丢失了。事实上,这就是为什么你会收到反对票,这正是我试图向你解释的。请尝试并注意,否则人们会相应地对待你。@Neillun My bad:(…验证并更新:p非常感谢详细的解释。特别是$in的替代方案和$map的使用也给了我一些其他查询的好主意:)非常感谢详细的解释。特别是$in的替代方案和$map的使用也给了我一些其他查询的好主意:)