具有条件的Mongodb聚合查找

时间:2018-01-30 09:40:01

标签: mongodb mongodb-query aggregation-framework

我有一个名为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,
}

现在我想执行MongoDB查询以查找title regex category_id,而8必须等于db.article.aggregate( { $match: { title: { $regex: /example/ } } }, { $lookup: { from: "article_category", pipeline: [ { $match: { category_id: 8 } } ], as: "article_category" } } ) 。这是我的查询,但不起作用。

regex

以上查询仅显示category_id匹配但v-for不匹配的记录。

有什么想法吗?

2 个答案:

答案 0 :(得分:8)

首先,它是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 })

答案 1 :(得分:1)

这里有几件事不正确。 category_id应为all_category_id。使用$lookup中的联接条件,并使用$match $lookup移动$unwind以外的$project进行optimized查找。

使用排除的{$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":[]}}}
])

对于不相关的子查询,请尝试

{{1}}