繁体   English   中英

如果嵌套的 object 满足 MongoDB 聚合中的条件,如何删除 object

[英]How to remove the object if the nested object meets the condition in MongoDB aggregation

我有一个包含地点相关数据的集合。 对于一个地方,可以有多个预订。 预订详细信息保存在另一个集合中。 这两个 collections 如下。

//place collection
{
    "_id" : ObjectId("5f0e01f3cd2767d8b9d1d884"),
    "name" : "abc"
}
//booking collection
/* 1 */
{
    "_id" : ObjectId("5f0e0260cd2767d8b9d1da32"),
    "placeId" : ObjectId("5f0e01f3cd2767d8b9d1d884"),
    "startDate" : ISODate("2020-07-25T00:00:00.000Z"),
    "endDate" : ISODate("2020-07-27T00:00:00.000Z")
}

/* 2 */
{
    "_id" : ObjectId("5f0e02e6cd2767d8b9d1dc38"),
    "placeId" : ObjectId("5f0e01f3cd2767d8b9d1d884"),
    "startDate" : ISODate("2020-07-29T00:00:00.000Z"),
    "endDate" : ISODate("2020-07-30T00:00:00.000Z")
}

所以我需要找到一个特定日期的可用位置。 所以我尝试了以下查询。

var date = ISODate("2020-07-25T00:00:00.000Z");
db.getCollection('place').aggregate([
{"$lookup":{"from":"booking","localField":"_id","foreignField":"placeId","as":"bookings"}},
{
   "$match":{
      "$or":[
         {"bookings.startDate":{"$gt":date}},
         {
            "$and":[
               {"bookings.startDate":{"$lte":date}},
               {"bookings.endDate":{"$lt":date}}
            ]
         }
      ]
   }
}
]);

结果是

{
    "_id" : ObjectId("5f0e01f3cd2767d8b9d1d884"),
    "name" : "abc",
    "bookings" : [ 
        {
            "_id" : ObjectId("5f0e0260cd2767d8b9d1da32"),
            "placeId" : ObjectId("5f0e01f3cd2767d8b9d1d884"),
            "startDate" : ISODate("2020-07-25T00:00:00.000Z"),
            "endDate" : ISODate("2020-07-27T00:00:00.000Z")
        }, 
        {
            "_id" : ObjectId("5f0e02e6cd2767d8b9d1dc38"),
            "placeId" : ObjectId("5f0e01f3cd2767d8b9d1d884"),
            "startDate" : ISODate("2020-07-29T00:00:00.000Z"),
            "endDate" : ISODate("2020-07-30T00:00:00.000Z")
        }
    ]
}

基本上如果这个特定的地方没有日期,那么结果不应该来。 但是在这里,对于这个地方它有多个预订,只有一个预订符合匹配条件。 所以如果一个预订数据符合标准,我需要删除整个结果。 我怎样才能做到这一点?

我尝试了$not条件的查询。

var date = ISODate("2020-07-28T00:00:00.000Z");
db.getCollection('place').aggregate([
{"$lookup":{"from":"booking","localField":"_id","foreignField":"placeId","as":"bookings"}},
{
   "$match":{
      "$or":[
         {"bookings.startDate":{"$not":{"$gt":date}}},
         { 
            "$and":[
               {"bookings.startDate":{"$not":{"$lte":date}}},
               {"bookings.endDate":{"$not":{"$lt":date}}}
            ]
         }
      ]
   }
}
]);

这适用于 25 日、26 日、27 日的日期。 但是对于 28,应该可以使用地方,但结果并没有出现。

我已经通过查找管道解决了这个问题,如下所示。

var date = ISODate('2020-07-28T00:00:00.000Z');
db.getCollection('place').aggregate([
{'$lookup':{
    'from':'booking',
    'let':{'place':'$_id','checkingDate':date},
    'pipeline': [{ '$match':{ 
                    '$expr':{
                        '$and':[
                            {'$eq':['$placeId','$$place']},
                            {'$not':{'$gt':['$startDate','$$checkingDate']}},
                            {'$not':{'$lt':['$endDate','$$checkingDate']}}
                         ]}}}
    ],
    'as':'bookings'
    }
}
,
{'$match':{'bookings':{ '$exists': 'true','$size': 0}}}
]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM