MongoDB Присоединиться к нескольким полям

Я переписываю SQL-запросы в mongoDB. Может кто-то помочь, как мы присоединяемся к двум коллекциям с несколькими ключами соединения и условиями, подобными ниже SQL Query.

SELECT S.* FROM LeftTable S
LEFT JOIN RightTable R ON S.ID =R.ID AND S.MID =R.MID WHERE R.TIM >0 AND S.MOB IS NOT NULL

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

db.dim.aggregate([{$lookup:{from:"dimFactsVer11",localField:"Sub", foreignField:"Type", as:"EmbedUp"}}])

Ответ 1

В настоящее время mongodb $lookup сравнивает только один локальный и внешний.

Но если вы хотите выполнить запрос, как и mysql left join с двумя или более файлами, то ниже это решение.

db.getCollection('LeftTable').aggregate([
{
    $lookup:
        {
          from: "RightTable",
          localField: "ID",
          foreignField: "ID",
          as: "RightTableData"
        }
},  
{$unwind :"$RightTableData" },
{ 
     $project: { 
            mid: { $cond: [ { $eq: [ '$MID', '$RightTableData.MID' ] }, 1, 0 ] } 
        } 
},
{$match : { mid : 1}}

])

Здесь $MID - это поле LeftTable MID.

Ответ 2

При правильной комбинации $lookup, $project и $match вы можете присоединиться к нескольким таблицам параметров. Это связано с тем, что они могут быть связаны несколько раз.

Шаг 1: Свяжите все таблицы

$lookup - по одному для каждой таблицы в запросе

$unwind - потому что данные денормализированы правильно, иначе они завернуты в массивы

Код Python.

db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "R"}

                       # {"$lookup": {
                       #   "from": "TopTable",
                       #   "localField": "ID",
                       #   "foreignField": "ID",
                       #   "as": "T"
                       # }},
                       # {"$unwind": "T"},

                        ])

Шаг 2: Определите все условные обозначения

$project: укажите здесь все условные операторы, а также все переменные, которые вы хотите выбрать.

Код Python..

db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "R"},

                       # {"$lookup": {
                       #   "from": "TopTable",
                       #   "localField": "ID",
                       #   "foreignField": "ID",
                       #   "as": "T"
                       # }},
                       # {"$unwind": "T"},

                        # define conditionals + variables

                        {"$project": {
                          "midEq": {"$eq": ["$MID", "$R.MID"]},
                         # "midGt": {"$gt": ["$MID", "$T.MID"]},
                          "ID": 1, "MOB": 1, "MID": 1
                        }}
                        ])

Шаг 3. Присоедините все условные обозначения

$match - присоединяться ко всем условиям, используя OR или AND и т.д. Их может быть несколько.

$project: undefine все условные обозначения

Код Python..

db.LeftTable.aggregate([
                        # connect all tables

                        {"$lookup": {
                          "from": "RightTable",
                          "localField": "ID",
                          "foreignField": "ID",
                          "as": "R"
                        }},
                        {"$unwind": "$R"},

                       # {"$lookup": {
                        #  "from": "TopTable",
                        #  "localField": "ID",
                        #  "foreignField": "ID",
                        #  "as": "T"
                        #}},
                        #{"$unwind": "$T"},

                        # define conditionals + variables

                        {"$project": {
                          "midEq": {"$eq": ["$MID", "$R.MID"]},
                          # "midGt": {"$gt": ["$MID", "$T.MID"]},
                          "ID": 1, "MOB": 1, "MID": 1
                        }},

                        # join all conditionals

                        {"$match": {
                          "$and": [
                            {"R.TIM": {"$gt": 0}}, 
                            {"MOB": {"$exists": True}},
                            {"midEq": {"$eq": True}},]
                        }},

                        # undefine conditionals

                        {"$project": {
                          "midEq": 0,
                          # "midGt": 0
                        }}

                        ])

Практически любая комбинация таблиц, условных обозначений и объединений может быть выполнена таким образом.