Как я могу найти с помощью 2 относительных свойств объекта массива в мангусте

#node.js #mongodb #mongoose #mongodb-query

Вопрос:

Таким образом, у пользователя есть 2 пользователя, за которыми он следит:

 "following": [{
        "userid": {
            "$oid": "60a933ebb35b4b3c788ee37c"        // say user A
        },
        "time": 1622147753992                       // when this user was followed (new Date().getTime())
    }, {
        "userid": {
            "$oid": "60a932edb35b4b3c788ee377"                   // user B
        },
        "time": 1622155516968
    }]
 

Я пытаюсь запросить уведомления, которые этот пользователь получит от пользователя и пользователя, датированные временем, когда за ними следили.

вот что я попробовал, получив приведенный выше список подписчиков:

 notificationModel.find({$and: [
                    {userid: following.userid},
                    {time: {$gte: following.time}}
                ]}).then(...
 

Этот запрос дает 0 результатов и без ошибок.
Поскольку у каждого пользователя есть свой момент, когда за ним следили, как я могу сравнить идентификатор пользователя и соответствующее ему время с идентификатором пользователя и временем уведомления?

Примечание: в следующем массиве может быть любое количество записей

Ответ №1:

Потому что ваш following массив таков following.userid и following.time будет undefined . Чтобы это сработало, вы можете сначала создать массив условий из этого массива, а затем использовать его с помощью $или для запроса. Что-то нравится:

 let conditions = following.map(e => ({
  userid: e.userid,
  time: {$gte: e.time}
}));

notificationModel.find({ $or: conditions });
 

Ответ №2:

Ваш идентификатор пользователя и время находятся внутри массива. Поэтому вам нужно использовать $elemMatch аннотацию или точечную аннотацию. Когда вы выполняете проекцию following.$ , она даст вам первый элемент массива, как сказано в документе «вы можете указать проекцию, чтобы вернуть первый элемент, соответствующий условию запроса в поле массива» . Документ

 db.collection.find({
  following: {
    "$elemMatch": {
      userid: "60a933ebb35b4b3c788ee37c",
      time: {
        $gte: 1622147753992
      }
    }
  }
},
{
  "following.$": 1
})
 

Рабочая игровая площадка Монго


Но если результат содержит несколько элементов внутри массива, вам нужно перейти к агрегациям

 db.collection.aggregate([
  {
    "$project": {
      following: {
        "$filter": {
          "input": "$following",
          cond: {
            $and: [
              {  $eq: [ "$this.userid", "60a933ebb35b4b3c788ee37c" ] },
              { "$gte": [ "$this.time", 1622147753992 ] }
            ]
          }
        }
      }
    }
  }
])
 

Рабочая игровая площадка Монго

Комментарии:

1. Нет, вы также можете использовать для нескольких элементов