すべてのarticle_category
を格納するarticle_id
というコレクションがあり、そのようなデータ形式のcategory_id
を持つカテゴリに属します。
コレクション1:article_category
{
"article_id": 2015110920343902,
"all_category_id": [5,8,10]
}
それから、私の投稿をすべて保存するarticle
という他のコレクションがあります
コレクション2:記事
{
"title": "This is example rows in article collection"
"article_id": 2015110920343902,
},
{
"title": "Something change"
"article_id": 2015110920343903,
},
{
"title": "This is another rows",
"article_id": 2015110920343904,
}
次に、category_id
が8
と等しくなければならないときに、title
でregex
を見つけるMongoDBクエリを実行します。ここに私のクエリがありますが、動作しません。
db.article.aggregate(
{
$match:
{
title:
{
$regex: /example/
}
}
},
{
$lookup:
{
from: "article_category",
pipeline: [
{ $match: { category_id: 8 } }
],
as: "article_category"
}
}
)
上記のクエリは、regex
で一致するがcategory_id
で一致しないレコードのみを表示します。
何か案が?
まず第一に、それはall_category_id
ではなくcategory_id
です。第二に、記事をリンクしないでください-すべてのドキュメントはまったく同じarticle_category
配列を持ちます。最後に、カテゴリに一致しない記事を除外することをお勧めします。条件付きパイプラインは次のようになります。
db.article.aggregate([
{ $match: {
title: { $regex: /example/ }
} },
{ $lookup: {
from: "article_category",
let: {
article_id: "$article_id"
},
pipeline: [
{ $match: {
$expr: { $and: [
{ $in: [ 8, "$all_category_id" ] },
{ $eq: [ "$article_id", "$$article_id" ] }
] }
} }
],
as: "article_category"
} },
{ $match: {
$expr: { $gt: [
{ $size: "$article_category"},
0
] }
} }
] )
更新:
article_id
と一致しない場合、$lookup
は、すべての記事と同じarticle_category
配列になります。
article_category
コレクションに別のドキュメントがあるとします。
{
"article_id": 0,
"all_category_id": [5,8,10]
}
{ $eq: [ "$article_id", "$$article_id" ] }
がパイプラインにある場合、結果のarticle_category
は
[
{
"article_id" : 2015110920343902,
"all_category_id" : [ 5, 8, 10 ]
}
]
なし:
[
{
"article_id" : 2015110920343902,
"all_category_id" : [ 5, 8, 10 ]
},
{
"article_id": 0,
"all_category_id": [ 5, 8, 10 ]
}
]
後者が必要な場合は、リクエストを見つけるのがはるかに簡単になります:
db.article.find({ title: { $regex: /example/ } })
そして
db.article_category.find({ all_category_id: 8 })
ここではいくつか間違っています。 category_id
はall_category_id
でなければなりません。 $lookup
で結合条件を使用し、$match
を optimized
ルックアップの$lookup
で$unwind
ステージの外に移動します。
$project
を除外して使用して、検索されたフィールドを最終応答から削除します。 {$project:{article_category:0}}
のようなもの
試して
db.article.aggregate([
{"$match":{"title":{"$regex":/example/}}},
{"$lookup":{
"from":"article_category",
"localField":"article_id",
"foreignField":"article_id",
"as":"article_category"
}},
{"$unwind":"$article_category"},
{"$match":{"article_category.all_category_id":8}}
])
非相関サブクエリの場合
db.article.aggregate([
{"$match":{"title":{"$regex":/example/}}},
{"$lookup":{
"from":"article_category",
"pipeline":[{"$match":{"all_category_id":8}}],
"as":"categories"
}},
{"$match":{"categories":{"$ne":[]}}}
])