【问题标题】:is there any query to find documents by checking a field of a nested embedded document in mongoDb是否有任何查询可以通过检查 mongoDb 中嵌套嵌入文档的字段来查找文档
【发布时间】:2020-06-10 04:57:06
【问题描述】:

这是我的产品架构。

const Products: Schema = new Schema({
storeId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'store',
    required: true
},
invoiceId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'invoice'
},
unitPrice: { type: Number },
quantity: { type: Number },

}, { timestamps: true });

这是我的发票架构

const invoice: Schema = new Schema({
customer: { type: String, default: null },

netTotal: { type: Number },
paid: { type: Number },
type: { type: String },

}, { timestamps: true });

我想查找 invoiceId 文档中类型为“sale”的产品。因为 invoiceId 是包含发票详细信息的产品文档中的嵌入文档。

我尝试过填充,但它不起作用。

Products.find().populate({path : "invoiceId" , match : {type : "sale"} });

但它不起作用,并且所有文件都只是填充那些“销售”的 invoiceId。

我们将不胜感激。

【问题讨论】:

  • 您确定您的ref: 'invoice' 正确吗?因为,通常它是复数形式,例如invoices
  • 是的,它是正确的。
  • 您只是在使用 Mongoose 时遇到了问题,还是 mongodb 查询也有帮助?
  • 您最好将示例文档和预期输出添加到问题中。
  • @AnujPancholi MongoDb 查询也会有所帮助。

标签: node.js database mongodb express mongoose


【解决方案1】:

免责声明:我还没有使用 Mongoose,但是在 cmets 中你说 mongodb 查询也会有帮助。

根据您描述的 Mongoose 模式,我使用 Mockeroo (https://mockaroo.com/) 模拟了 10 个产品文档和 3 个发票文档。请注意,此处的 objectIds 只是被视为整数,但只要所有 id 都是 objectIds,查询就应该可以正常工作。

产品

{
  "_id": 1,
  "storeId": 1,
  "invoiceId": 3,
  "unitPrice": 127,
  "quantity": 21,
  "timestamp": "1558330027"
},
{
  "_id": 2,
  "storeId": 2,
  "invoiceId": 2,
  "unitPrice": 140,
  "quantity": 25,
  "timestamp": "1552293229"
},
{
  "_id": 3,
  "storeId": 1,
  "invoiceId": 2,
  "unitPrice": 192,
  "quantity": 80,
  "timestamp": "1576270154"
}, //and so on...

发票

{
  "_id": 1,
  "customer": "Y-find",
  "netTotal": 1,
  "paid": true,
  "type": "stale"
},
{
  "_id": 2,
  "customer": "Namfix",
  "netTotal": 72,
  "paid": true,
  "type": "sale"
},
{
  "_id": 3,
  "customer": "Opela",
  "netTotal": 67,
  "paid": false,
  "type": "fail"
}

由于每个产品都存储一个 invoiceId,因此 products-invoices 是多对一的关系(因为许多产品可能具有相同的 invoiceId,因此属于同一张发票,但是,我们不会存储任何产品的具体参考在发票中,并且每个产品只有一个 invoiceId,因此,一个产品必须只属于一个发票)。

我们的目标是编写查询以获取发票类型为“销售”的所有产品。为此,我编写了以下聚合:

db.products.aggregate([
{
    $lookup: {
        "from": "invoices",
        "let": {
            inv_id: "$invoiceId"
        },
        "pipeline": [
        {
            $match: {
                $expr: {
                    $eq: [
                        "$$inv_id",
                        "$_id"
                    ]
                }
            }
        }
        ],
        as: "invoice"
    }
  },
  {
      $unwind: {
          path: "$invoice"
      }
  },
  {
      $match: {
        "invoice.type": "sale"
      }
  },
  {
      $unset: "invoice"
  }
])

我把 mock 数据放到 Mongoplayground 中试了一下,这里是: https://mongoplayground.net/p/K8ciQ-Ei12P

请注意,最后一个 $unset 阶段只是为了确保结果中的所有文档都只是没有发票详细信息的产品文档(因为这是必需的)。

希望它有所帮助。如果有人有任何优化要指出,或者可以将其转换为 Mongoose,请随意。

【讨论】:

    猜你喜欢
    • 2018-03-09
    • 2021-11-12
    • 2015-07-14
    • 2021-02-25
    • 2016-08-16
    • 2018-09-04
    • 2016-07-01
    • 1970-01-01
    相关资源
    最近更新 更多