MongoDB - обрабатывать несуществующие массивы в $ в запросе - PullRequest
0 голосов
/ 14 октября 2019

У меня есть следующий запрос:

db.getCollection('authors').aggregate([
  { $match: {} }, 
  { $sort: { name: -1 } }, 
  { $addFields: { x_id___as___string: { $toString: "$_id" } } }, 
  { $lookup: {
      from: "books",
      let: { fkField:"$x_id___as___string" },
      pipeline: [{ $match: { $expr: { $in: ["$$fkField", "$authorIds"] } } }],
      as: "books"
    } 
  }
])

, который работает нормально, , если * * * * * не указан массив authorIds в некоторых из объединенных документов, и в этом случае я получаю ошибкуиз

"errmsg": "$ in требует массив в качестве второго аргумента, найдено: отсутствует", "код": 40081, "codeName": "Location40081"}: агрегат не выполнен

Я подтвердил, что добавление authorIds в виде пустого массива к документам, пропущенным вручную, исправляет запрос. Мой вопрос:

Как настроить этот запрос для работы с несуществующим полем authorIds?

Должен ли я изменить свой $expr на$and запрос, с первым значением проверка на наличие массива? Гарантирует ли Mongo короткое замыкание ? Есть ли более простая проверка, которую я могу просто добавить к запросу $in?

1 Ответ

1 голос
/ 14 октября 2019

добавьте $ cond в конвейер поиска $ expr

db.getCollection('authors').aggregate([
  { $match: {} }, 
  { $sort: { name: -1 } }, 
  { $addFields: { x_id___as___string: { $toString: "$_id" } } }, 
  { $lookup: {
      from: "books",
      let: { fkField:"$x_id___as___string" },
      pipeline: [{ $match: { $expr: { $in: ["$$fkField", {$cond: {if: {$gt: ["$authorIds", null]}, then: "$authorIds", else: []}}] } } }],
      as: "books"
    } 
  }
])

, который проверит, существует ли authorIds. Чтобы убедиться, что это фактический массив, вы можете использовать $isArray

db.getCollection('authors').aggregate([
  { $match: {} }, 
  { $sort: { name: -1 } }, 
  { $addFields: { x_id___as___string: { $toString: "$_id" } } }, 
  { $lookup: {
      from: "books",
      let: { fkField:"$x_id___as___string" },
      pipeline: [{ 
        $match: { 
          $expr: { 
            $in: [
              "$$fkField", 
              { $cond: { if: { $isArray: "$authorIds" }, then: "$authorIds", else: [] } }
            ] 
          } 
        } 
      }],
      as: "books"
    } 
  }
])
...