как присоединиться к схеме в mongodb?
Пример :
Коллекция
{
ObjectId : ObjectId("ABCDE")
userName : "Jason",
level : 30,
money : 200
}
b коллекция
{
Id : ObjectId("AAACC"),
userId : ObjectId("ABCDE"),
item : "sword"
}
б. агрегировать ....
я хочу результат id: ObjectId ("AAACC"), userName: "Jason", item: "sword"
@SergeyBerezovskiy Да, буду обрабатывать исключения по данным.
Вы должны использовать конвейер агрегации, чтобы объединить две коллекции и выбрать необходимые данные. Я предполагаю, что у вас есть правильные поля идентификации с именем _id
вместо ObjectId
и Id
, как в вашем примере:
db.items.aggregate([
{
$lookup:
{
from: "users",
localField: "userId",
foreignField: "_id", // ObjectId in your sample
as: "user"
}
},
{ $unwind: "$user" },
{
$project:
{
"item": 1,
"userName": "$user.userName"
// Id: 1 if you will use your names, because only _id is selected by default
}
}
])
Первый шаг - это Погляди, который объединяет коллекции Предметы и пользователи в поле userId
, равном полю _id
в коллекции пользователей.
Затем вы должны получить результаты размотать, потому что поиск помещает всех совпавших пользователей в поле user
как массив пользовательских документов.
И последний шаг - проект приведите документы в желаемый формат.
Теперь образец. Если у вас есть следующие документы в коллекции Предметы:
{
"_id" : ObjectId("5c18df3e5d85eb27052a599c"),
"item" : "sword",
"userId" : ObjectId("5c18ded45d85eb27052a5988")
},
{
"_id" : ObjectId("5c18df4f5d85eb27052a599e"),
"item" : "helmet",
"userId" : ObjectId("5c18ded45d85eb27052a5988")
},
{
"_id" : ObjectId("5c18e2da5d85eb27052a59ee"),
"item" : "helmet"
}
И у вас есть два пользователя:
{
"_id" : ObjectId("5c18ded45d85eb27052a5988"),
"userName" : "Jason",
"level" : 30,
"money" : 200
},
{
"_id" : ObjectId("5c18dee35d85eb27052a598a"),
"userName" : "Bob",
"level" : 70,
"money" : 500
}
Тогда приведенный выше запрос даст
{
"_id" : ObjectId("5c18df3e5d85eb27052a599c"),
"item" : "sword",
"userName" : "Jason"
},
{
"_id" : ObjectId("5c18df4f5d85eb27052a599e"),
"item" : "helmet",
"userName" : "Jason"
},
{
"_id" : ObjectId("5c18e2da5d85eb27052a59ee"),
"item" : "helmet"
}
ПРИМЕЧАНИЕ. Обычно имена пользователей должны быть уникальными. Рассмотрите возможность использования их в качестве идентификатора для коллекции пользователи. Это также даст вам желаемый результат в коллекции Предметы без каких-либо объединений.
спасибо, это очень хороший ответ !!
Вы можете использовать оператор агрегации Погляди для объединения обеих коллекций, а затем проект только для интересующего вас поля из коллекции a:
db.b.aggregate([
{
$lookup: {
from: "a",
localField: "userId",
foreignField: "ObjectId",
as: "user"
}
},
{
$unwind: "$user"
},
{
$project: {
Id: 1
userName: "$user.userName",
item: 1
}
}
]);
Я предполагаю, что a.ObjectId
на самом деле должен называться a._id
, а b.Id
должен называться b._id
? В любом случае применяется тот же принцип.
Обновлено: забыл этап размотать. Это необходимо, поскольку поиск вернет новое объединенное поле в виде массива (хотя и с одним элементом), поэтому вам нужно избавиться от квадратных скобок.
Можно ли иметь предметы, которые не принадлежат ни одному пользователю?