Как использовать $ map в проекции MongoDB $ - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть база данных с такими документами:

{
   _id: 123, 
   metrics: [{ 
               _id: ObjectID(…), 
               name: 'foo',
               steps: [1, 2, 3, …], 
               values: [10, 12, 13, …]
              },
              { 
               _id: ObjectID(…), 
               name: 'bar',
               steps: [1, 2, 3, …], 
               values: [1.2, 1.2, 1.3, …]
              },
             ]
}

Теперь моя цель - получить все документы, но $map все записи массива с их атрибутом name, отбрасывая другие поля.Я думал, что мог бы сделать это так:

pipeline = [{'$project': {'metrics': {'$map': {'input': '$metrics', 'in': '$this.name'}]
results = client.db.runs.aggregate(pipeline)

Но результат имеет всего None значений для каждой записи массива ({'metrics': [None, None, None, …]}), как если бы запрошенное поле name не существовало.Но это так.Я также пытался с полем id, но безрезультатно.При проверке данных я вижу, что поля есть.Я не могу понять, что я делаю здесь неправильно.

1 Ответ

0 голосов
/ 01 февраля 2019

Внутри $ map вы можете использовать as, чтобы определить временную переменную, которая будет представлять отдельный документ из вашего metrics, а затем ссылаться на эту переменную в части in.

db.col.aggregate([{'$project': {'metrics': {'$map': {'input': '$metrics', as: 'metric', 'in': '$$metric.name' } } } }])

или вы можете напрямую ссылаться на временную переменную this

db.col.aggregate([{'$project': {'metrics': {'$map': {'input': '$metrics', 'in': '$$this.name' } } } }])

Дело в том, что каждый раз, когда вы используете один знак доллара, вы ссылаетесь на поле, определенное вдокумент, который обрабатывается на текущей стадии конвейера.Кроме того, вы можете использовать двойной знак доллара для ссылки на некоторые переменные, которые могут быть определены операторами, такими как $map, $filter и т. Д.

Вы можете попробовать свой исходный код для следующего документа:

{
    _id: 123, 
    this: { name: "x" },
    metrics: [{ }, { } ]
}

и вы получите массив с двумя значениями x, поскольку есть две метрики, но каждая итерация ссылается на одно и то же значение this.x:

{ "_id" : 123, "metrics" : [ "x", "x" ] }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...