$ lookup, когда localField является вложенным - PullRequest
0 голосов
/ 03 июля 2018

MongoDB версия 3.4.10 (Приложение использует Meteor Framework)

Цель : Объединить документы, на которые ссылается _id, в содержащий документ, как требуется во время выполнения.

У меня есть коллекции Materials, Models и Catalog со следующими документами:

Материалы

 { "_id" : "cf4KgXw7ZK6ukdzR7", "name" : "parquet_wood_mahogany" }

Модель

{
  "_id" : "Mwp5eYYZ4GZzvZuoK",
  "name" : "top_square_chamfered",
  "type" : "top"
}
{
  "_id" : "CqhS2m2RcLZ2Bm4eb",
  "name" : "skirt_square",
  "type" : "skirt"
}
{
  "_id" : "dYP22ajALnWBwpBj2",
  "name" : "leg_square",
  "type" : "leg"
}

Каталог

{
  "_id" : "EcRGzPAq79giYKrbY",
  ...,
  "specs" : {
    ...,
    "models" : [
      {
        "mesh" : "Mwp5eYYZ4GZzvZuoK",
        "material" : "cf4KgXw7ZK6ukdzR7"
      },
      {
        "mesh" : "CqhS2m2RcLZ2Bm4eb",
        "material" : "cf4KgXw7ZK6ukdzR7"
      },
      {
        "mesh" : "dYP22ajALnWBwpBj2",
        "material" : "cf4KgXw7ZK6ukdzR7"
      }
    ]
  }
}

Желаемый Возвращенный формат документа после агрегирования:

{
  "_id" : "EcRGzPAq79giYKrbY",
  ...,
  "specs" : {
    "dimensions" : {
      ...,
    },
    "models" : [
      {
        "mesh" : {
          "_id" : "Mwp5eYYZ4GZzvZuoK",
          "name" : "top_square_chamfered",
          "type" : "top"
        },
        "material" : {
          "_id" : "cf4KgXw7ZK6ukdzR7",
          "name" : "parquet_wood_mahogany"
        }
      },
      {
        "mesh" : {
          "_id" : "CqhS2m2RcLZ2Bm4eb",
          "name" : "skirt_square",
          "type" : "skirt"
        },
        "material" : {
          "_id" : "cf4KgXw7ZK6ukdzR7",
          "name" : "parquet_wood_mahogany"
        }
      },
      {
        "mesh" : {
          "_id" : "dYP22ajALnWBwpBj2",
          "name" : "leg_square",
          "type" : "leg"
        },
        "material" : {
          "_id" : "cf4KgXw7ZK6ukdzR7",
          "name" : "parquet_wood_mahogany"
        }
      }
    ]
  }
}

Я не включил ни один из своих кодов запросов, потому что они настолько далеки от истины, что это просто шум. Я пытался использовать aggregate с $lookup комбинациями, но я не подхожу близко к тому, что мне нужно. Синтаксис MongoDB v3.6 pipeline сделает это намного проще ... но я в полной нерешительности в v3.4.

Я бы хотел избежать использования нескольких запросов к базе данных для объединения этой информации, если это вообще возможно. Любая помощь совета будет принята с благодарностью!

РЕДАКТИРОВАТЬ: Рабочий раствор -

db.catalog.aggregate([
  { "$lookup": {
    "from": 'models',
    "localField": "specs.models.mesh",
    "foreignField": "_id",
    "as": "models.mesh"
  }},
  { "$lookup": {
    "from": 'materials',
    "localField": "specs.models.material",
    "foreignField": "_id",
    "as": "models.material"
  }},
  { "$unwind": "$models.mesh" },
  { "$unwind": "$models.material" },
  { "$group":{
    "_id": "$_id",
    "title": { "$first": "$title" },
    "desc": { "$first": "$desc" },
    "thumbnail": { "$first": "$thumbnail" },
    "createdBy": { "$first": "$createdBy" },
    "createdAt": { "$first": "$createdAt" },
    "specs": { "$first": "$specs" },
    "models": { "$push": "$models" }
  }},
  { "$project": {
    "_id": "$_id",
    "title": "$title",
    "desc": "$desc",
    "thumbnail": "$thumbnail",
    "createdBy": "$createdBy",
    "createdAt": "$createdAt",
    "specs.dimensions": "$specs.dimensions",
    "specs.models": "$models",
  }}
])

1 Ответ

0 голосов
/ 03 июля 2018

Вы можете попробовать ниже агрегации

db.catalog.aggregate([
  { "$lookup": {
    "from": 'models',
    "localField": "specs.models.mesh",
    "foreignField": "_id",
    "as": "models.mesh"
  }},
  { "$lookup": {
    "from": 'materials',
    "localField": "specs.models.material",
    "foreignField": "_id",
    "as": "models.material"
  }},
  { "$unwind": "$models.mesh" },
  { "$unwind": "$models.material" },
  { "$group":{
    "_id": "$_id",
    "title": { "$first": "$title" },
    "desc": { "$first": "$desc" },
    "thumbnail": { "$first": "$thumbnail" },
    "createdBy": { "$first": "$createdBy" },
    "createdAt": { "$first": "$createdAt" },
    "specs": { "$first": "$specs" },
    "models": { "$push": "$models" }
  }},
  { "$project": {
    "title": "$title",
    "desc": "$desc",
    "thumbnail": "$thumbnail",
    "createdBy": "$createdBy",
    "createdAt": "$createdAt",
    "specs.dimensions": "$specs.dimensions",
    "specs.models": "$models",
  }}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...