简体   繁体   English

如何使用聚合从 mongodb 中的两个 collections 查询?

[英]How to query from two collections in mongodb using aggregate?

I have the two following collections in my mongoDB:我的 mongoDB 中有两个以下 collections:

PRODUCTS:产品:

[
    {
        "_id": "5ebb0984e95e3e9e35aab3bf",
        "name": "Product 1",
        "brand": "ABC",
        "code": "7891910000190",
        "description": "Lorem Ipsum"
    },
    {
        "_id": "5ebdb9f3d943ae000a4a9714",
        "name": "Product 2",
        "brand": "DEF",
        "code": "7891910000190",
        "description": "Lorem Ipsum"
    }
]

STOCK GOODS:库存商品:

[
    {
        "_id": "5ed0586b7f2cfe02387d0706",
        "companyId": "5ed0491bf9a892a5fd9b4d9b",
        "branchId": "5ed049a8f9a892a5fd9b4d9e",
        "inventoryId": "5ed04d01e9e43cee79734b95",
        "productId": "5ebb0984e95e3e9e35aab3bf"
    },
    {
        "_id": "5ed058da75e4e01013f5779d",
        "companyId": "5ed0491bf9a892a5fd9b4d9b",
        "branchId": "5ed049a8f9a892a5fd9b4d9e",
        "inventoryId": "5ed04cede9e43cee79734b93",
        "productId": "5ebb0984e95e3e9e35aab3bf"
    },
    {
        "_id": "5ed059483da3bafccb34cec3",
        "companyId": "5ed0491bf9a892a5fd9b4d9b",
        "branchId": "5ed049a8f9a892a5fd9b4d9e",
        "inventoryId": "5ed04d01e9e43cee79734b95",
        "productId": "5ebb0984e95e3e9e35aab3bf"
    }
]

I want to get the follow result:我想得到以下结果:

[
    {
        "_id": "5ed0586b7f2cfe02387d0706",
        "data": {
            "_id": "5ebb0984e95e3e9e35aab3bf",
            "brand": "ABC",
            "code": "7891910000190",
            "description": "Lorem Ipsum",
            "name": "Product 1",
        }
    },
    {
        "_id": "5ed059483da3bafccb34cec3",
        "data": {
            "_id": "5ebb0984e95e3e9e35aab3bf",
            "brand": "ABC",
            "code": "7891910000190",
            "description": "Lorem Ipsum",
            "name": "Product 1",
        }
    }
]

My NodeJS and MongoDB aggregate look like this:我的 NodeJS 和 MongoDB 聚合如下所示:

const mongoose = require("mongoose");
const StockGoods = mongoose.model("StockGoods");
ObjectId = require("mongodb").ObjectID;

exports.getProducts = async (companyId, branchId, inventoryId) => {
  const response = await StockGoods.aggregate([
    {
      $match: {
        companyId: new ObjectId("5ed0491bf9a892a5fd9b4d9b"), // new ObjectId(companyId)
        inventoryId: new ObjectId("5ed04d01e9e43cee79734b95"), // new ObjectId(inventoryId)
        branchId: new ObjectId("5ed049a8f9a892a5fd9b4d9e"), // new ObjectId(branchId)
      },
    },
    {
      $lookup: {
        from: "products",
        localField: "productId",
        foreignField: "_id",
        as: "inventory_docs",
      },
    },
    {
      $project: {
        data: "$inventory_docs",
      },
    },
    { $unwind: "$data" },
  ]);
  return response;
};

This is the same database and the aggregate function described above, you can check this: https://mongoplayground.net/p/FRgAIfO2bwh .这是同一个数据库和上面描述的聚合 function,你可以检查这个: https://mongoplayground.net/p/FRgAIfO2bwh

But, this function aggregate does not working when I use nodejs.但是,当我使用 nodejs 时,这个 function 聚合不起作用。 My API returns nothing (empty array).我的 API 什么都不返回(空数组)。

Whats wrong?怎么了?

Issue here is the way you have stored data in collection.... StockGoods collection has companyId, inventoryId and branchIdas a string but aggregation is looking for ObjectId aee below match criteria:这里的问题是您在集合中存储数据的方式...... StockGoods 集合有 companyId、inventoryId 和 branchIdas 字符串,但聚合正在寻找符合条件的 ObjectId aee:

 $match: {
    companyId: new ObjectId("5ed0491bf9a892a5fd9b4d9b"), // new ObjectId(companyId)
    inventoryId: new ObjectId("5ed04d01e9e43cee79734b95"), // new 
    ObjectId(inventoryId)
    branchId: new ObjectId("5ed049a8f9a892a5fd9b4d9e"), // new ObjectId(branchId)
  },

Based on the data you store in DB either you need to update match with string.根据您存储在数据库中的数据,您需要使用字符串更新匹配。

So below Aggregation will work for you..所以下面的聚合将为你工作..

[
 {
  "$match": {
     "companyId": "5ed0491bf9a892a5fd9b4d9b",
     "inventoryId": "5ed04d01e9e43cee79734b95",
     "branchId": "5ed049a8f9a892a5fd9b4d9e"
  }
  },
 {
  "$lookup": {
     "from": "products",
     "localField": "productId",
     "foreignField": "_id",
     "as": "inventory_docs"
  }
  },
 {
  "$project": {
     "data": "$inventory_docs"
  }
 },
{
  "$unwind": "$data"
}

] ]

This works you can test in Compass Aggregator这可以在 Compass Aggregator 中测试在此处输入图像描述 tab标签

[RESOLVED] [解决]

The problem was in the scheme:问题出在方案中:

companyId: {
    type: String,
    required: true,
},

The correct is:正确的是:

companyId: {
    type: Schema.Types.ObjectId,
    required: true,
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM