私は2つのコレクションを持っています
ユーザー
{
"_id" : ObjectId("584aac38686860d502929b8b"),
"name" : "John"
}
役割
{
"_id" : ObjectId("584aaca6686860d502929b8d"),
"role" : "Admin",
"userId" : "584aac38686860d502929b8b"
}
serId(in roleコレクション)-_ id(in serコレクション)に基づいてこれらのコレクションに参加したい。
私は以下のクエリを試しました:
db.role.aggregate(
{
$lookup:
{
from: 'user',
localField: 'userId',
foreignField: '_id',
as: 'output'
}
}
);
これにより、userIdをObjectIdとして保存している限り、期待される結果が得られます。 userIdが文字列の場合、結果はありません。 Ps:試した
foreignField: '_id'.valueOf()
そして
foreignField: '_id'.toString()
。しかし、ObjectId文字列フィールドに基づいて一致/結合する運はありません。
任意の助けをいただければ幸いです。
これは、MongoDB 3.4以降では不可能です。この機能は既にリクエストされていますが、まだ実装されていません。対応するチケットは次のとおりです。
今のところ、userIdをObjectIdとして保存する必要があります
[〜#〜] edit [〜#〜]
以前のチケットは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"
}
]
}
]
オンラインで試してください: mongoplayground.net/p/JoLPVIb1OLS
$toObjectId
mongodbからの集約4.0String id
をObjectId
に変換します
db.role.aggregate([
{ "$lookup": {
"from": "user",
"let": { "userId": "$_id" },
"pipeline": [
{ "$addFields": { "userId": { "$toObjectId": "$userId" }}},
{ "$match": { "$expr": { "$eq": [ "$userId", "$$userId" ] } } }
],
"as": "output"
}}
])
または、 $toString
mongodbからの集約4.0ObjectId
をString
に変換します
db.role.aggregate([
{ "$addFields": { "userId": { "$toString": "$_id" }}},
{ "$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "userId",
"as": "output"
}}
])
前の回答には、「$ toObjectId」の場合にエラーがあると思います。 let
ステートメントは、関数aggregate
が呼び出されるdbコレクション(つまり「ロール」)に適用され、「from」(つまり「ユーザー」)が指すコレクションには適用されません。
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"
}}
])