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

时间:2017-08-10 13:45:20

标签: mongodb mongodb-query aggregation-framework

数据:

[

{
    "_id" : ObjectId("597c48d222b29fc421e82d20"),
    "Date" : "12/06/2017",
    "Country" : "DEMO",
    "RiderId" : "DEMO",
    "VehicleId" : "DEMO",
    "StartAddress" : "Colombo",
    "StartLocation" : [ 
        6.9270974, 
        79.8612478
    ],
    "EndAddress" : "Kegalle,",
    "EndLocation" : [ 
        7.2476005, 
        80.3483415
    ],
    "DepartureAddress" : "Dellogistics International (Pvt) Ltd, Colombo 04",
    "DepartureLocation" : [ 
        6.8824893, 
        79.8620031
    ],
    "ArrivalAddress" : "Osro, Kegalle",
    "ArrivalLocation" : [ 
        7.2476005, 
        80.3483415
    ],
    "IsLadiesOnly" : false,
    "Notes" : "\"I'm travalleing from Bambalapitiya to Kegalle, small luggages are ok\"",
    "Luggage" : 2.0,
    "Detours" : 1.0,
    "Route" : {
        "Bounds" : {
            "NorthEast" : [ 
                7.2916216, 
                80.6341326
            ],
            "SouthWest" : [ 
                6.9270974, 
                79.8607731
            ]
        },
        "Legs" : [ 
            {
                "LegId" : 0.0,
                "Distance" : 40033.0,
                "Duration" : 4725.0,
                "Price" : "240",
                "StartAddress" : "Colombo",
                "StartLocation" : [ 
                    6.9270974, 
                    6.9270974
                ],
                "EndAddress" : "Nittambuwa",
                "EndLocation" : [ 
                    7.1420863, 
                    80.1038061
                ],
                "Ancestors" : []
            }, 
            {
                "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"
                ]
            }
        ]
    },
    "CreatedDate" : "2017-01-06T07:00:00.000Z",
    "ModifiedDate" : "01/06/2017 12:30",
    "Points" : "123"
}]

查询是:

 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 ] }
                          ]
                        }
                }
             }
          }}

    ])

基本在条件内我需要查询集合并获取腿部ID进行比较。我试过$ where但是它不能识别条件下的操作符。

另外,为什么我不能在cond中使用$ where,$ nin

1 个答案:

答案 0 :(得分:2)

您通常需要通过在外部$filter内嵌套另一个$filter来应用条件,该$map查找匹配的数组条目并匹配条件。然后应用$arrayElemAt$gte实际提供$indexOfArray条件的"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 ] }  
          ]
        }
      }
    }
  }}
])

由于&#34;多个条件&#34>,您无法真正在此处应用$nin这样的内容来获取数组索引。需要匹配数组元素。

虽然没有&#34;直接&#34;等同于$setIntersection作为&#34;逻辑运算符&#34;对于聚合条件,您可以使用替代方案。在这里,我申请$size,因为它可能是最好的比较两个&#34; unique&#34;阵列。逻辑说明当&#34;交叉路口的$nin&#34;是0,那里没有匹配。因此符合与$and相同的标准。

当然&#34;倍数&#34;条件都由RowData包裹,因为它就是它的作用。

结果当然会过滤匹配条件的"LegId"值与&#34; end&#34;之间的数组项。提供的值,即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"
            ]
        }
    ]
}

全部从提供的数据中复制和粘贴,并在此处发布声明的结果。