MongoDB, как найти документы с неопределенными поисками $ (агрегация) - PullRequest
0 голосов
/ 17 мая 2019

У меня есть документ в исходной коллекции, который содержит ИЛИ, но не содержит ссылку на иностранный документ коллекции - ключ не является обязательным, поэтому иногда он отсутствует.

В такой ситуации поиск $ «не выполнен», и нужный документ не извлекается из БД.

Это конвейер:

{
    $lookup: {
      from: "tables",
      let: { "enginefuel_type": "$engine.fuel_type" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$enginefuel_type"] }}},
        { $project: { title: 1 }}
      ],
      as: "engine.fuel_type"
    }
  },
  {
    $unwind: "$engine.fuel_type"
  },

  {
    $lookup: {
      from: "tables",
      let: { "enginegear": "$engine.gear" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$enginegear"] }}},
        { $project: { title: 1 }}
      ],
      as: "engine.gear"
    }
  },
  {
    $unwind: "$engine.gear"
  }

Мне все равно нужно найти документ - независимо от того, имеет ли он поля engine.fuel_type и / или engine.gear или нет. Если есть, значит, он должен взять документ у иностранного, иначе просто оставить пустым, но не игнорировать весь документ.

Я подумал о том, чтобы сделать некоторую проверку перед выражением if, если поле существует, перед выполнением агрегированного запроса (также может быть более эффективным, сокращая запросы к БД).

Есть ли хороший способ сделать это?

1 Ответ

1 голос
/ 17 мая 2019

Этап поиска работает так, как вам нужно, даже если поле не присутствует в исходной коллекции, документ не будет проигнорирован и будет частью результата с массивом «engine.fuel_type», содержащим 0 элементов.

Этап разматывания удаляет документы с 0 элементами массива. К счастью, $ unwind stage предоставляет preserveNullAndEmptyArrays: параметр, который включает в себя весь результат. Таким образом, вы можете попробовать сделать что-то вроде этого: -

$lookup: {
      from: "tables",
      let: { "enginefuel_type": "$engine.fuel_type" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$enginefuel_type"] }}},
        { $project: { title: 1 }}
      ],
      as: "engine.fuel_type"
    }
  },
  {
    $unwind: {
      path: "engine.fuel_type",
      preserveNullAndEmptyArrays: true
    }
  }
...