简体   繁体   English

根据MongoDB中一个文档的另一文档的属性获取结果

[英]Get result based on property of another document from one document in MongoDB

I have two documents -我有两个文件——

const taskSchema = new mongoose.Schema({
    leadId: { type: String, default: '' },
    customer_name: { type: String, default: '' }
})

const leadSchema = new mongoose.Schema({
  Id: { type: String, default: "" },
  associate_status: { type: Boolean, default: false },
})

I want to run a query on tasks such that I get all the leads where associate status is true.我想对任务运行查询,以便获得关联状态为真的所有潜在客户。

LeadId in task schema is the same as Id in the lead schema.任务架构中的LeadId与潜在客户架构中的Id相同。

I tried this -我试过这个 -

  const report = await taskModel.aggregate([
   { $lookup: {
      from: 'leads',
      let: { leadId: '$leadId' },
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: ['$Id', '$$leadId'],
            },
          },
        },
      ],
      as: 'leaditems',
    },
  }
  { $unwind: '$leaditems' },
  { $match: { leaditems.associate_status: true}}
 ])

But since I have a large number of documents (more than 200k leads and 100k tasks, and these numbers will keep on growing), the query sometimes runs after 9 to 10 seconds and sometimes doesn't runs at all.但是由于我有大量文档(超过 200k 潜在客户和 100k 任务,并且这些数字将继续增长),查询有时会在 9 到 10 秒后运行,有时根本不运行。 I am looking for a more optimized approach or any other implementation that will make this work.我正在寻找一种更优化的方法或任何其他可以使这项工作发挥作用的实现。

Update:更新:

I tried this as well but no improvement -我也试过这个,但没有改善 -

const report = await taskModel.aggregate([
       { $lookup: {
          from: 'leads',
          let: { leadId: '$leadId' },
          pipeline: [
            {
              $match: {
                $expr: {
                  $and: [
                   {
                     $eq: ['$Id', '$$leadId'],
                   },
                   {
                     $eq: ['$associate_status', true],
                   },
                 ],
               },
              },
            },
          ],
          as: 'leaditems',
        },
      }
     ])

Put $match condition in $lookup pipeline or even try to put it before $lookup .$match条件放在$lookup pipeline ,甚至尝试将其放在$lookup之前。

Set index on both associated id.在两个关联的 id 上设置index

Maybe your service has a 10 second database connection constraint, try to make it longer.也许你的服务有一个 10 秒的数据库连接限制,试着让它更长。

To use the index in $exp inside a lookup pipeline you need MongoDB 5. MongoDB 4.4.9 will not use the index and query will be slow.要在查找管道内使用$exp的索引,您需要 MongoDB 5。MongoDB 4.4.9 不会使用索引,查询会很慢。

  • create the indexes in leads and Id, its expected to be much faster在 Leads 和 Id 中创建索引,预计速度会更快
    (index helps if it has good selectivity, if select small percentage of the documents, an index that will return 90% of documents can make things worse)(if you add many values on leadId index will be updated also, it can cost, but the benefits most of the times are much more) (如果索引具有良好的选择性,它会有所帮助,如果选择一小部分文档,将返回 90% 文档的索引会使事情变得更糟)(如果您在 LeadId 索引上添加许多值也将被更新,它会花费,但是大多数时候的好处更多)
  • replace with a simple equality $lookup替换为简单的相等$lookup
  • Also if you dont really need the $unwind and you prefer your data in array you can use $filter此外,如果您真的不需要$unwind并且您更喜欢数组中的数据,则可以使用$filter
const report = await taskModel.aggregate([
       { $lookup: {
          from: 'leads',
          localField: "leadId",
          foreignField: "Id",
          as : "leaditems"
       },
       { $unwind: '$leaditems' },
       { $match: { leaditems.associate_status: true}}       
     ])

If possible benchmark it after you do those and send some feedback.如果可能的话,在你完成这些并发送一些反馈后对其进行基准测试。

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

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