Часть проекта MongoDB элемента массива - PullRequest
1 голос
/ 09 июля 2020

Я пытаюсь создать проекцию, в которой я могу взять только часть элемента Array.

Возьмите этот документ в качестве модели:

{
    "city_info": {
        "name": "First City"
        "initials": "FC"
    },
    "postal_codes": {
        "ranges": [
            {
                "name": "Range 1",
                "details": "More details",
                "another_object": {
                   (...)
                },
                "codes": [
                    {"code": 1},
                    {"code": 2},
                    {"code": 3}
                ]
            },
            {
                "name": "Range 2",
                "details": "More details 2",
                "another_object": {
                   (...)
                }
                "codes": [
                    {"code": 4},
                    {"code": 5}
                ]
            }
        ]
    }
}

Мой запрос будет выглядеть как {"postal_codes.ranges.codes.code": 3}

Диапазоны и коды могут иметь сотни элементов. Например, «другой_объект» - это просто заполнитель.

Ожидаемый результат будет примерно таким:

{
    "city_info": {
        "name": "First City"
        "initials": "FC"
    },
    "range": {
        "name": "Range 1",
        "details": "More details",
        "another_object": {
            (...)
        }
    }         
}

Короче говоря, мне нужно получить элемент массива, который также соответствует запросу, но не возвращайте его полностью.

Кажется, что find недостаточно мощный, мне понадобится какое-то агрегирование. Я попытался использовать совпадение, чтобы вернуть только те документы, которые соответствуют запросу, но я не знаю, как проецировать только часть массива.

Ответы [ 2 ]

2 голосов
/ 09 июля 2020

У вас недопустимая структура codes. Это не может быть вставлено в Mongodb

"codes": [
  "code": 1,
  "code": 2,
  "code": 3
]

Если вам нужно сохранить три кода, действительным JSON будет

"codes": [
  1,2,3
]

Итак, пример данных:

{
    "_id" : ObjectId("5f074307e96d8884b6bdbdd5"),
    "city_info" : {
        "name" : "First City",
        "initials" : "FC"
    },
    "postal_codes" : {
        "ranges" : [ 
            {
                "name" : "Range 1",
                "details" : "More details",
                "another_object" : {},
                "codes" : [ 
                    1, 
                    2, 
                    3
                ]
            }, 
            {
                "name" : "Range 2",
                "details" : "More details 2",
                "another_object" : {},
                "codes" : [ 
                    4, 
                    5
                ]
            }
        ]
    }
}

Запрос для получения:

db.getCollection('test2').aggregate([
  {
    $unwind: "$postal_codes.ranges"
  },
  {
    $unwind: "$postal_codes.ranges.codes"
  },
  {
    $match: {
      "postal_codes.ranges.codes": 3
    }
  }

])

Вывод:

/* 1 */
{
    "_id" : ObjectId("5f074307e96d8884b6bdbdd5"),
    "city_info" : {
        "name" : "First City",
        "initials" : "FC"
    },
    "postal_codes" : {
        "ranges" : {
            "name" : "Range 1",
            "details" : "More details",
            "another_object" : {},
            "codes" : 3
        }
    }
}

Чтобы избежать codes в выводе, вам нужно использовать $project в качестве последнего конвейера

{
 $project:{"postal_codes.ranges.codes":0}
}
1 голос
/ 09 июля 2020

Вам нужно использовать $ unwind для преобразования Array в Objects , а затем использовать $ match

Попробуйте этот запрос,

db.collection.aggregate([
  { "$unwind": "$postal_codes" },
  { "$unwind": "$postal_codes.ranges.codes"},
  { "$match" : { "postal_codes.ranges.codes" : { "$eq": 3 } }},
  { "$project" : { "city_info": 1, "ranges": "$postal_codes.ranges" }}
])

Надеюсь, это может вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...