Как написать mongodb-запрос для запроса только определенного поля из массива документов? - PullRequest
1 голос
/ 26 марта 2020

Я только начал изучать mongodb и застрял в проблеме. У меня есть следующая схема сбора:

{
     "address":string,
      "users" : [{"id":integer, "timestamp":integer}] //users is an array of documents

}

Я хочу написать запрос, который принесет мне все идентификаторы пользователей для определенного адреса, учитывая, что они находятся в пределах определенного периода времени. Т.е. условия:

1) адрес: данный_адрес

И

2) данный_имень времени <= временная метка <= данный_временная отметка + Х </p>

Отслеживать, как мне запрашивая ТОЛЬКО идентификаторы пользователей вместо всех документов, я попытался установить

$project:{address:0,users.id:1 , users.timestamp:0 } 

, но это вызвало у меня ошибку.

Ответы [ 2 ]

1 голос
/ 26 марта 2020

Вы должны использовать конвейер агрегации для этого:

db.collection.aggregate([
  /** Filter docs where address: "abcd" */
  { $match: { address: "abcd" } },
  /** Re-create 'users' array field with elements which match given condition,
   *  it will empty array if nothing matched */
  {
    $addFields: {
      users: {
        $filter: {
          input: "$users",
          cond: {
            $and: [
              { $gte: ["$$this.timestamp", 12] },
              { $lte: ["$$this.timestamp", 1500] }
            ]
          }
        }
      }
    }
  }
]);

Тест: MongoDB-Playground

1 голос
/ 26 марта 2020

$projection является избыточным.

Попробуйте это:

db.user.find({"$and" : [{"address" : "xxx"}, {"users.timestamp" : {"$gte" : 12}}, {"users.timestamp" : {"$lte" : 200}}]}, {"users.id" : 1})

Также по умолчанию поля не возвращаются, поэтому вам не нужно устанавливать {"address" : 0, "users.timestamp" : 0}

...