Mongodb точная сумма $ для фильтра $ и $ map или $ unwind - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть схема с несколькими вложенными массивами.Я хочу получить сумму определенного элемента на основе определенного запроса.

Это мой запрос.

ОБНОВЛЕНИЕ

Если кто-то спрашиваетпочему эта структура?Мне нужна была система, в которой обновление точки может быть выполнено один раз, без необходимости искать несколько мест, прежде чем обновление будет успешно завершено без ошибок.Может быть несколько операций обновления, и если все эти массивы будут преобразованы в крошечные объекты, то обновление элемента может стать очень серьезной, утомительной и проблемной задачей.

db.getCollection('cuisine').aggregate([
{$match: {
        first_level:{
        $elemMatch:{
            "first_item":"United kingdom",
            "second_item":"Great Britian",
            "third_item":"England",
            second_level:{
            $elemMatch:{
                second_lev_one:"London",
                third_level:{
                $elemMatch:{
                    third_lev_one:"city of london",
                    fourth_level:{
                    $elemMatch:{
                        fourth_lev_one:"crab donut",
                        fourth_lev_two:"Chillout place"
                    }
                    }
                }
                }
            }
            }
        }
        }
    }},
{"$addFields":{
    "first_level":{
    "$filter":{
    "input":{
    "$map":{
        "input":"$first_level",
        "as":"firstlev",
        "in":{
            "_id":"$$firstlev._id",
            "second_level":{
            "$filter":{
            "input":{
            "$map":{
                "input":"$$firstlev.second_level",
                "as":"sec_lev",
                "in":{
                    "_id":"$$sec_lev._id",
                    "second_lev_one":"$$sec_lev.second_lev_one",
                    "third_level":{
                    "$filter":{
                    "input":{
                    "$map":{
                        "input":"$$sec_lev.third_level",
                        "as":"third_lev",
                        "in":{
                            "_id":"$$third_lev._id",
                            "third_lev_one":"$$third_lev.third_lev_one",
                            "fourth_level":{
                            "filter":{
                            "input":"$$third_lev.fourth_level",
                            "as":"fourth_lev",
                                "cond":{
                                "$and": [
                                    { "$eq": [ "$$fourth_lev.fourth_lev_one", "crab donut"] },
                                    { "$eq": [ "$$fourth_lev.fourth_lev_two","Chillout place" ] }
                                ]
                                }
                            }
                            }
                        }
                    }
                    },
                    "as":"third_lev",
                    "cond":{
                    "$and": [
                        { "$eq": [ "$$third_lev.third_lev_one", "city of london"] },
                        { "$ne": [ "$$third_lev.fourth_level",[] ] }
                    ]
                    }
                    }
                    }
                }
            }
            },
            "as":"sec_lev",
            "cond":{
            "$and": [
                { "$eq": [ "$$sec_lev.second_lev_one", "London" ] },
                { "$ne": [ "$$sec_lev.third_level",[] ] }
            ]
            }
            }
            }
        }
    }
    },
    "as":"class",
    "cond": {
    "$and": [
        { "$eq": [ "$$class.first_item", "United kingdom" ] },
        { "$eq": [ "$$class.second_item", "Great Britian" ] },
        { "$eq": [ "$$class.third_item", "England" ] },
        { "$ne": [ "$$class.second_level",[] ] }
    ]
    }
    }
    }
}},
{"$group":{
    "_id":{
        "first_item":"$first_level.first_item",
        "third_item":"$first_level.third_item",
        "second_lev_one":"$first_level.second_level.second_lev_one",
        "third_lev_one": "$first_level.second_level.third_level.third_lev_one",
        "fourth_lev_two":"$first_level.second_level.third_level.fourth_level.fourth_lev_two",
        "fourth_lev_one":"$first_level.second_level.third_level.fourth_level.fourth_lev_one",
        "total_price":"$first_level.second_level.third_level.fourth_level.price"
    },
    "Totalprice":{
        "$sum": "$first_level.second_level.third_level.fourth_level.price"
    }
}}
]);

это вывод, который я получаю (когдая использую $ filter $ map)

{ "_id" : 
{ "first_item" : [ "United kingdom" ], "third_item" : [ "England" ], "second_lev_one" : [ [ "London" ] ], 
    "third_lev_one" : [ [ [ "city of london" ] ] ], "fourth_lev_two" : [ [ [ [ "Chillout place", "Chillout place" ] ] ] ], 
    "fourth_lev_one" : [ [ [ [ "crab donut", "crab donut" ] ] ] ], "total_price" : [ [ [ [ 20, 20 ] ] ] ] }, 
"Totalprice" : 0 }

это не суммирование общей цены, которая находится внутри массива.Я ожидал, что это будет 40, но это приносит 0. Кроме этого я не знаю, почему это помещает результат в массив.Я использую $ filter $ map.Я не использовал $ unwind, потому что это не дает мне точных данных.Пожалуйста, как я могу получить сумму, а также показать основной результат вместо того, чтобы показывать его внутри массива? Любая помощь будет приветствоваться

, но когда я использую $ unwind

{ "_id" : { "first_item" : "United kingdom", "third_item" : "England", "second_lev_one" : "London", "third_lev_one" : "city of london", "fourth_lev_two" : "Chillout place", "fourth_lev_one" : "crab donut", "total_price" : 20 }, "Totalprice" : 40 },
{ "_id" : { "first_item" : "United kingdom", "third_item" : "England", "second_lev_one" : "London", "third_lev_one" : "city of london", "fourth_lev_two" : "Chillout place", "fourth_lev_one" : "fried chicken", "total_price" : 20 }, "Totalprice" : 20 }

Некоторые вещиЯ хочу добиться, чтобы 1. подсчитать количество предметов, которые были найдены в total_price (в результате выше есть два предмета)

получить общую сумму предметов в общей цене, которая будет отображаться в Totalprice

выполнить некоторые арифметические операции, такие как вычитание некоторых результатов из другого поля, например, если другое полепроизводится, например, по индивидуальной цене с такими пунктами, как [[[[15,10]]]] , а затем вычитает отдельные элементы из другого поля, как в этом случае [[[[20,20]]]] и выдайте результат [[[[5,10]]]], а также получите в общей сложности 15

перед выполнением некоторых операций на полена полевые операции, например, [[[[15,10]]]] * 1.5 результат, который нужно вычесть из [[[[20,20]]]].

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

Раздел данных

{ "_id" : ObjectId("5bbf975759a97c1094a200b2"),
    "first_level" : [
        { "_id" : ObjectId("5bbf975759a97c1094a200b3"),
        "staff_id" : ObjectId("5b8b5abb518a1a0a601a18d0"),
        "first_item" : "United kingdom", 
        "second_item" : "Great Britian", 
        "third_item" : "England", 
        "second_level" : [
            { "_id" : ObjectId("5bc786bea967e812cc986a79"), "second_lev_one" : "Yorkshire and the Humber"}, 
            { "_id" : ObjectId("5bc786dda967e812cc986a7d"), "second_lev_one" : "East of England" }, 
            { "_id" : ObjectId("5bd7ef5eca682d1b34ff6b85"), "second_lev_one" : "London", "third_level" : [
                {   "_id" : ObjectId("5bd7ef5eca682d1b34ff6b88"), "third_lev_one" : "city of london", "fourth_level" : [
                        { "_id" : ObjectId("5bd8060a8ef0fc173c8aa597"), "price" : 20, "sales_date" : ISODate("2018-10-30T00:00:00Z"), "fourth_lev_one" : "crab donut", "fourth_lev_two" : "Chillout place" },
                        { "_id" : ObjectId("5bd806128ef0fc173c8aa599"), "price" : 20, "sales_date" : ISODate("2018-10-30T00:00:00Z"), "fourth_lev_one" : "crab donut", "fourth_lev_two" : "Chillout place" }, 
                        { "_id" : ObjectId("5be266b60cecc912681f7c48"), "price" : 20, "sales_date" : ISODate("2018-11-06T00:00:00Z"), "fourth_lev_one" : "fried chicken", "fourth_lev_two" : "Chillout center"} ] },
                { "_id" : ObjectId("5bd7ef5eca682d1b34ff6b8a"), "third_lev_one" : "City of Westminster", "fourth_level" : [ ] }, 
                { "_id" : ObjectId("5bd7ef5eca682d1b34ff6b8c"), "third_lev_one" : "Kensington and Chelsea", "fourth_level" : [ ] }, 
                { "_id" : ObjectId("5bd7ef5eca682d1b34ff6b8e"), "third_lev_one" : "Hammersmith and Fulham", "fourth_level" : [ ] }, 
                { "_id" : ObjectId("5bd7ef5eca682d1b34ff6b90"), "third_lev_one" : "Wandsworth", "fourth_level" : [ ] }, 
                { "_id" : ObjectId("5bd7ef5eca682d1b34ff6b92"), "third_lev_one" : "Lambeth", "fourth_level" : [ ] }

            ] } 
        ]}

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