Mongo:管道 $lookup 中的 $exists 未按预期工作

时间:2021-05-07 10:15:54

标签: mongodb mongodb-query nosql aggregation-framework

我的两个系列是:


product_category

{
    "_id" : ObjectId("5fca496b61e8a83e5cd0fb01"),
    "category_id" : "1",
    ...
}

产品

{
    "_id" : ObjectId("60684610f8f81d0013ce776d"),
    "primary_parent_category" : "1653",
    ...
}

在$lookup中使用localfield和foreignfield,可以达到预期的效果。

db.getCollection('product_category').aggregate([
    {
    "$lookup": {
        "from": "product",
        "localField": "category_id",
        "foreignField": "primary_parent_category",
        "as": "products"
    }
    },
//     { "$match": { "products": { $exists: true, $not: { $size: 0 } } }},
    { "$match": { "products": { $exists: true, $ne: [] } }},
    {
    "$project":{
        "child_categories": 0,
        "featured_products": 0,
        "related_brands": 0,
        "child_category_names": 0
    }
    }
])

以上工作正常,但我必须将 $lookup 中的管道模型用于另一个用例(用于添加 $geoNear)。聚合查询如下。

db.getCollection('product_category').aggregate([
    {
    "$lookup": {
        "from": "product",
        "let": { "category_id": "$category_id" },
        "pipeline": [
             { "$match": { "product": { $exists: true, $ne: [] } }},      
             {
                 "$project":{
                     "child_categories": 0,
                     "featured_products": 0,
                     "related_brands": 0,
                     "child_category_names": 0
                 }
             }
        ],
        "as": "products"
    }
    }
])

这没有按预期工作并返回大量条目。 $match 中的 $exists 没有得到正确执行。 任何帮助表示赞赏。提前致谢。

2 个答案:

答案 0 :(得分:1)

正如@turivishal 所指出的,您必须在管道参数的 $expr 中使用 $match 运算符。您必须在尝试使用 $$ 引用临时 MongoDB 变量的任何地方执行此操作。

{
  $match: {
    {
      $expr: {"$eq": ["$$<VAR-NAME-IN-LET>", "$<FOREIGN-KEY-IN-TARGET-COL>"]}
    }
  }
}
db.getCollection('product_category').aggregate([
  {
    "$lookup": {
      "from": "product",
      "let": { "category_id": "$category_id" },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              { $eq: [ "$primary_parent_category",  "$$category_id" ] },
            }
            "product": { 
              $exists: true,
              $ne: [],
            },
          }
        },      
        {
          "$project":{
              "child_categories": 0,
              "featured_products": 0,
              "related_brands": 0,
              "child_category_names": 0
          }
        }
      ],
      "as": "products"
    }
  }
])

答案 1 :(得分:1)

正确的方法是结合@hhharsha36 和@turivishal 提到的内容。我不得不在 $lookup 块之后移动 $exist 的匹配查询,变量映射匹配块完好无损。

db.getCollection('product_category').aggregate([
  {
    "$lookup": {
      "from": "product",
      "let": { "category_id": "$category_id" },
      "pipeline": [
    {
      "$match": {
        "$expr": 
          { "$eq": [ "$primary_parent_category",  "$$category_id" ] },
      }},
    {
      "$project":{
          "child_categories": 0,
          "featured_products": 0,
          "related_brands": 0,
          "child_category_names": 0
      }
    }
      ],
      "as": "products"
    }
  },
  { "$match": 
      { "products": 
      { 
          "$exists": true,
          "$ne": [],
      } 
      } 
   },
])