Поддокумент запроса MongoDB для записей, не соответствующих критериям - PullRequest
0 голосов
/ 18 февраля 2020

В настоящее время у меня есть следующий запрос:

db.getCollection('conversations').aggregate([
{
  $lookup: {
    foreignField: "c_ID",
    from: "messages",
    localField: "_id",
    as: "messages"
  }
},
{
  "$unwind": "$messages"
},
{
  "$sort": {
    "messages.t": -1
  }
},
{
  "$group": {
    "_id": "$_id",
    "lastMessage": {
      "$first": "$messages"
    },
    "allFields": {
      "$first": "$$ROOT"
    }
  }
},
{
  "$replaceRoot": {
    "newRoot": {
      "$mergeObjects": [
        "$allFields",
        {
          "lastMessage": "$lastMessage"
        }
      ]
    }
  }
},
{
  $project: {
    messages: 0
  }
},
{
  $match: {
    "members.uID": "1",
    //"lastMessage.t": { $gt: ISODate("2020-02-04 20:38:02.154Z") }
  }
},
{
  $sort: { "lastMessage.t": 1 }
},
{
  $limit: 10
},
{
  $project: {
    members: {
      $slice: [ {
        $filter: {
          input : "$members", as : "member", cond : {
            $ne : ["$$member.uID" , "1"]
          }
        }
      }, 3 ]
    }
  }
},

])

Однако у меня также есть поле для каждого члена с именем "l", которое содержит метку времени. Это означает, что кто-то оставил разговор и, таким образом, представляет дату ухода. Я не хочу, чтобы кто-либо, кто ушел до текущей отметки времени (например, 1582056056), был включен в список участников. Как я могу это сделать?

РЕДАКТИРОВАТЬ:

документ разговоров

{
    "_id" : ObjectId("5e35f2c840713a43aeeeb3d9"),
    "members" : [ 
        {
            "uID" : "1",
            "j" : 1580580922
        }, 
        {
            "uID" : "4",
            "j" : 1580580922,
            “l”: 1580581982
        }, 
        {
            "uID" : "5",
            "j" : 1580580922
        }
    ]
}

документ сообщений

{
    "_id" : ObjectId("5e35ee5f40713a43aeeeb1c5"),
    "c_ID" : ObjectId("5e35f2c840713a43aeeeb3d9"),
    "fromID" : "1",
    "msg" : "What's up?",
    "t" : 1580591922,
    "d" : {
        "4" : 1580592039
    },
    "r" : {
        "4" : 1580592339
    }
}

1 Ответ

0 голосов
/ 19 февраля 2020

Мы можем исключить их во время $filter этапа с операторами $and и $or.

member.uID != 1 && (member.l == undefined || lastMessage.t < member.l)

Посмотрите запрос ниже.

db.conversations.aggregate([
  {
    $lookup: {
      from: "messages",
      foreignField: "c_ID",
      localField: "_id",
      as: "messages"
    }
  },
  {
    "$unwind": "$messages"
  },
  {
    "$sort": {
      "messages.t": -1
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "lastMessage": {
        "$first": "$messages"
      },
      "allFields": {
        "$first": "$$ROOT"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
          "$allFields",
          {
            "lastMessage": "$lastMessage"
          }
        ]
      }
    }
  },
  {
    $project: {
      messages: 0
    }
  },
  {
    $match: {
      "members.uID": "1"
    }
  },
  {
    $sort: {
      "lastMessage.t": 1
    }
  },
  {
    $limit: 10
  },
  {
    $project: {
      members: {
        $slice: [
          {
            $filter: {
              input: "$members",
              as: "member",
              cond: {
                $and: [
                  {
                    $ne: [
                      "$$member.uID",
                      "1"
                    ]
                  },
                  {
                    $or: [
                      {
                        $eq: [
                          "$$member.l",
                          undefined
                        ]
                      },
                      {
                        $lt: [
                          "$lastMessage.t",
                          "$$member.l"
                        ]
                      }
                    ]
                  }
                ]
              }
            }
          },
          3
        ]
      }
    }
  }
])

MongoPlayground

...