Присоединение / поиск по схеме мангуста - PullRequest
3 голосов
/ 22 марта 2019

В настоящее время я делаю систему достижений и пытаюсь сохранить ее в двух коллекциях.Одна коллекция, которая содержит имя и идентификатор, и другие коллекции с пользователями и их прогрессом.

Я смотрел на Агрегацию и на $ lookup, и добился некоторого прогресса, но я не уверен, чтобыло бы необходимо сделать, чтобы сделать желаемый вывод, который я хотел бы.

Если пользователь существует в достижениях, получить значение прогресса и его идентификатор пользователя с коллекцией, если нет, установить значение прогресса в 0.

Разве это не может быть какое-то присоединение, например, к Mysql ?, как это будет в MongoDB?

переменная userid = 33;

попытка:

db.getCollection('achievements').aggregate([
   {
     $lookup:
       {
         from: "achievement_users",
         localField: "id",
         foreignField: "id",
         as: "inventory_docs"
       }
  }
])

схема достижений:

{
    "name" : "testing",
    "id" : 1,
    "max" : 12,
},

{
    "name" : "testing2",
    "id" : 2,
    "max" : 12,

}

пользователь достижений:

{
    "userid" : 33,
    "id" : 1,
    progress: 1,
},
 {
        "userid" : 446,
        "id" : 1,
        progress: 1,
    }

Желаемый результат:

{
name: "testing",
id: 1,
userid: 33,
progress: 1,
    max : 12,

},
{
name: "testing2",
id: 2,
progress: 0,
    max : 12,

},

РЕДАКТИРОВАТЬ:

Мне нужны все достижения, которыепользователь сделал, а не сделал (не сделал = прогресс = 0).

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

обновление 2: также нужно, чтобы он давал мне результаты, когда нет совпадений в достижении_пользователей для этого специального идентификатора пользователя.

Ответы [ 2 ]

1 голос
/ 22 марта 2019

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

db.achievement_users.aggregate([
  { "$match": { "userid": 33 }},
  { "$lookup": {
    "from": "achievement",
    "let": { "id": "$id", "progress": "$progress", "userid": "$userid" },
    "pipeline": [
      { "$addFields": {
        "progress": { "$cond": [{ "$eq": ["$id", "$$id"] }, "$$progress", 0] },
        "userid": "$$userid"
      }}
    ],
    "as": "inventory_docs"
  }},
  { "$unwind": "$inventory_docs" },
  { "$replaceRoot": { "newRoot": "$inventory_docs" }}
])
1 голос
/ 22 марта 2019

Вот решение, если вы хотите выполнить что-то похожее на LEFT JOIN:

db.test.aggregate([{
    $lookup: {
        from: "user",
        localField: "id",
        foreignField: "id",
        as: "inventory_docs"
    }
}, {
    $unwind: {path: "$inventory_docs", preserveNullAndEmptyArrays: true }
}, {
    $addFields: {
        userid: "$inventory_docs.userid",
        progress: {$cond: {if: "$inventory_docs.progress", then: "$inventory_docs.progress", else: 0 }},
    }
}, {
    $project: {
        inventory_docs: 0
    }
}])

$lookup создать массив из объединенной коллекции

$unwind разбить массивв записях

$addFields извлеките нужное поле, как хотите

$cond замените пустой прогресс на 0

$project для окончательной очистки

...