Запросите идентификатор пользователя для наличия одного условия и ОТСУТСТВИЯ другого

#mongodb #mongodb-query

Вопрос:

Не могли бы вы, пожалуйста, помочь мне с этим? У меня есть эти документы:

 {
   userId: 123,
   event: 'A',
   properties: {
     status: 'Sent'
   }
}
{
   userId: 123,
   event: 'B',
   properties: {
     status: 'Opened'
   }
}
{
   userId: 123,
   event: 'C',
   properties: {
     status: 'Clicked'
   }
}
 

Мне нужен запрос , соответствующий всем userId == 'A' , которые также зарегистрировались для события «B», но не выполнили событие «C» properties.status == "Clicked" .

Вот что я сделал до сих пор:

 db.collection.aggregate([
{ $match: { "event": "A"} },
{
    $lookup: {
        from: "collection",
        let: { "userId": "$userId" },
        pipeline: [{
            $match: {
              $expr: { $eq: ["$userId", "$userId"] } 
            }
        }],
        as: "events"
    }
}
 

Это дает мне этот унифицированный вывод:

 {
   userId: 123,
   event: "A",
   properties: {
     status: 'Sent'
   },
   events: [
     { event: 'A' /* and all the other fields from original document */ },
     { event: 'B' /* and all the other fields from original document */ },
     { 
       event: 'C', 
       properties: {
         status: 'Clicked'
       }
     },
   ]
 

Я попытался сделать это в следующий раз, но это не сработало:

 {
    $match: {
        $expr: {
            $not: {
                $and: [
                    { $eq: ["$events.event", "C"] },
                    { $eq: ["$events.properties.status', 'Clicked'] }
                ]
            }

        }
    }
}
 

Я ожидаю, что этот запрос не приведет меня userId: 123 в данном случае, но он зависит от результатов.

Может кто-нибудь, пожалуйста, помочь мне с этим? Ткс!

Ответ №1:

В итоге я сделал это, добавив эти шаги после поиска. Не уверен, что это лучшее решение, но я не мог добиться этого никаким другим способом, который я пробовал.

 { $unwind: "$events"},
{
    $project: {
        "userId": 1, "events": "$events",
        "exclude": {
            $cond: { if: { 
                        $and: [
                            { $eq: ["$events.event", "C"] },
                            { $eq: ['$events.properties.status', 'Clicked'] }
                        ]
                 }, then: 1, else: 0 }
        }
    }
},
{ 
   $group: {
       _id: "$userId",
       exclude: { $sum: "$exclude"  }
   }
},
{
    $match: { "exclude": 0 }
}