mongodb 使用$lookup连表后 过滤从表无效

假如我有两个表,一张是商品表,数据如下

/* 1 */
{
    "_id" : "1",
    "productName" : "java"
},

/* 2 */
{
    "_id" : "2",
    "productName" : "c++"
},

/* 3 */
{
    "_id" : "3",
    "productName" : "c#"
}

一张是订单表,一个商品对应多个订单

/* 1 */
{
    "_id" : "0001",
    "product_id" : "1",
    "price" : 18
},

/* 2 */
{
    "_id" : "0002",
    "product_id" : "1",
    "price" : 30
}

现在我使用lookup 连表,同时查询商品价格等于18的,我发现他把不等于18的也查询出来了,sql如下

db.test_product.aggregate([
  {
    "$lookup": {
      "from": "test_order",
      "localField": "_id",
      "foreignField": "product_id",
      "as": "orderList"
    }
  },
  {
    "$match": {
      "_id": "1",
      "orderList.price": {
        "$eq": 18
      }
    }
  },
  {
    "$project": {
      "_id": 1,
      "productName": 1,
      "orderList": 1
    }
  }
])

结果是空集。

问题可能出在 $lookup 的 localField 和 foreignField 上。根据文档的描述,localField 是连接的左表的字段名称,而 foreignField 是右表的字段名称。在你的代码中,localField 是 "_id",而 foreignField 是 "product_id"。而在商品表中,_id 应该对应商品表中的主键字段,而 product_id 应该对应订单表中的商品字段。

如果你想在商品表中查询 id 为 1 的商品的订单,应该使用下面的查询:

db.test_product.aggregate([
  {
    "$lookup": {
      "from": "test_order",
      "localField": "_id",
      "foreignField": "product_id",
      "as": "orderList"
    }
  },
  {
    "$match": {
      "_id": "1",
      "orderList.price": {
        "$eq": 18
      }
    }
  },
  {
    "$project": {
      "_id": 1,
      "productName": 1,
      "orderList": 1
    }
  }
])

$match 操作符中的条件需要改成

"orderList.price": {
    "$eq": 18
}

这样就能获取到在订单表中,与商品表id为1且价格为18的订单信息。