我有两个收藏品
用户
{
"_id" : ObjectId("584aac38686860d502929b8b"),
"name" : "John"
}
作用
{
"_id" : ObjectId("584aaca6686860d502929b8d"),
"role" : "Admin",
"userId" : "584aac38686860d502929b8b"
}
我想基于 userId (在角色集合中)加入这些集合 - _id (在用户 >收藏)。
我尝试了以下查询:
db.role.aggregate(
{
$lookup:
{
from: 'user',
localField: 'userId',
foreignField: '_id',
as: 'output'
}
}
);
只要我将userId存储为ObjectId,这就给了我预期的结果。当我的userId是一个字符串时,没有结果。 Ps:我试过了
foreignField:' _id' .valueOf()
和
foreignField:' _id' .toString()
。但是基于ObjectId-string字段匹配/加入没有运气。
任何帮助将不胜感激。
答案 0 :(得分:13)
您可以使用mongodb 4.0 中的$toObjectId
聚合,它将字符串for dict in list:
for key, value in dict.iteritems():
# do something with key or value
转换为id
ObjectId
或者您可以使用mongodb 4.0 中的$toString
聚合将db.role.aggregate([
{ "$lookup": {
"from": "user",
"let": { "userId": "$_id" },
"pipeline": [
{ "$addFields": { "userId": { "$toObjectId": "$userId" }}},
{ "$match": { "$expr": { "$eq": [ "$userId", "$$userId" ] } } }
],
"as": "output"
}}
])
转换为ObjectId
String
答案 1 :(得分:9)
从MongoDB 3.4开始,这是不可能的。此功能已被请求,但尚未实施。以下是相应的门票:
现在你必须将userId存储为ObjectId
修改强>
之前的门票已在MongoDB 4.0中修复。您现在可以使用以下查询来实现此目的:
db.user.aggregate([
{
"$project": {
"_id": {
"$toString": "$_id"
}
}
},
{
"$lookup": {
"from": "role",
"localField": "_id",
"foreignField": "userId",
"as": "role"
}
}
])
结果:
[
{
"_id": "584aac38686860d502929b8b",
"role": [
{
"_id": ObjectId("584aaca6686860d502929b8d"),
"role": "Admin",
"userId": "584aac38686860d502929b8b"
}
]
}
]
答案 2 :(得分:0)
我认为先前的答案在'$ toObjectId'情况下有错误。 let
语句适用于在其上调用功能aggregate
(即'role')的db集合,而不适用于“ from”(即'user')所指向的集合。
db.role.aggregate([
{ "$lookup": {
"let": { "userObjId": { "$toObjectId": "$userId" } },
"from": "user",
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$userObjId" ] } } }
],
"as": "userDetails"
}}
])
或
db.role.aggregate([
{ "$project": { "userObjId": { "$toObjectId": "$userId" } } },
{ "$lookup": {
"localField": "userObjId",
"from": "user",
"foreignField": "$_id",
"as": "userDetails"
}}
])
和
db.user.aggregate([
{ "$project": { "userStrId": { "$toString": "$_id" }}},
{ "$lookup": {
"localField": "userStrId",
"from": "role",
"foreignField": "userId",
"as": "roleDetails"
}}
])