MongoDB在深层嵌套文档上的$ lookup

时间:2019-08-03 05:35:42

标签: mongodb mongodb-query mongodb-lookup

我最近第一次开始使用MongoDB,并尝试对嵌套文档执行左联接(查找)。据称,我通过阅读本网站上已有的答案找出了解决问题的方法。但是,我的查询量很大,我敢打赌,有一种更好的方法可以执行它。

在“报告”集合中,每个文档包含一个类别数组,每个类别包含一个子类别数组,每个子类别包含一个事务列表。

报告

{
        "_id" : ObjectId("5d3361d92a38c86359f51eea"),
        "card" : "4580...",
        "name" : "John Doe",
        "report_date" : ISODate("2019-06-01T00:00:00Z"),
        "categories" : [
                {
                        "title" : "Class 1",
                        "subcategories" : [
                                {
                                        "transactions" : [
                                                {
                                                        "purchase_date" : ISODate("2019-05-14T00:00:00Z"),
                                                        "business_name" : "Restaurant",
                                                        "original_amount" : 23,
                                                        "original_currency" : "$",
                                                        "final_amount" : 23,
                                                        "final_currency" : "$",
                                                        "id" : "02201022",
                                                        "details" : ""
                                                },
                                                {
                                                        "purchase_date" : ISODate("2019-05-17T00:00:00Z"),
                                                        "business_name" : "Flower shop",
                                                        "original_amount" : 30,
                                                        "original_currency" : "$",
                                                        "final_amount" : 30,
                                                        "final_currency" : "$",
                                                        "id" : "4903871",
                                                        "details" : "",
                                                }
                                        ],
                                        "sum" : {
                                                "original_amount" : 53,
                                                "final_amount" : 53,
                                                "original_currency" : "$",
                                                "final_currency" : "$",
                                                "date" : ISODate("2019-06-01T00:00:00Z")
                                        }
                                },
                                {
                                        "transactions" : [
                                                {
                                                        "purchase_date" : ISODate("2019-05-25T00:00:00Z"),
                                                        "business_name" : "Cash withdrawal",
                                                        "original_amount" : 100,
                                                        "original_currency" : "$",
                                                        "final_amount" : 100,
                                                        "final_currency" : "$",
                                                        "id" : "0120070",
                                                        "details" : ""
                                                }
                                        ],
                                        "sum" : {
                                                "original_amount" : 100,
                                                "final_amount" : 100,
                                                "original_currency" : "$",
                                                "final_currency" : "$",
                                                "date" : ISODate("2019-05-26T00:00:00Z")
                                        }
                                }
                        ]
                }
        ]
}

我也有“预期”收藏集:

预期

{
    "_id": ObjectId("5d43396264ae143ae41bf34f"),
    "card": "4580...",
    "date": ISODate("2019-05-25T00:00:00Z"),
    "business_name": "Cash withdrawal",
    amount: 100,
    currency: "$",
    owner: "John Doe"
}

我正在尝试获取报告,但是每笔交易都包含来自“ expected”的一系列匹配项。 查询条件:

  1. report.card =预期卡片
  2. report.name =预期所有者
  3. transaction.purchase_date =预期日期
  4. transaction.business_name =预期的业务名称
  5. transaction.original_amount =预期量
  6. transaction.original_currency =预期货币

以下查询有效,但如上所述,我认为它太复杂了:

db.reports.aggregate([
  {$unwind:"$categories"},
  {$unwind:"$categories.subcategories"},
  {$unwind:"$categories.subcategories.transactions"},
  {$lookup: {
    from: "expected",
    let: {
      owner: "$name",
      card: "$card",
      date: "$categories.subcategories.transactions.purchase_date",
      business: "$categories.subcategories.transactions.business_name",
      amount: "$categories.subcategories.transactions.original_amount",
      currency: "$categories.subcategories.transactions.original_currency"
    },
    pipeline: [
      { $match:
        { $expr:
          { $and:
            [
              { $eq: ["$$owner", "$owner"] },
              { $eq: ["$$card", "$card"] },
              { $eq: ["$$date", "$date"] },
              { $eq: ["$$business", "$business_name"] },
              { $eq: ["$$amount", "$amount"] },
              { $eq: ["$$currency", "$currency"] }
            ]
          }
        }
      }
    ],
    as: 'categories.subcategories.transactions.expected'
  }},
  {$group: 
    { _id: {
        _id: "$_id",
        card: "$card",
        name: "$name",
        report_date: "$report_date",
        category_title: "$categories.title",
        subcategories_sum: "$categories.subcategories.sum"
    },
    transactions: {
        $push: '$categories.subcategories.transactions',
    },
    sum: {
        $first: '$categories.subcategories.sum'
    }
  }},
  {$project: { subcategories: {transactions: '$transactions', sum: '$sum'}}},
  {$group: 
    { _id: {
        _id: "$_id._id",
        card: "$_id.card",
        name: "$_id.name",
        report_date: "$_id.report_date",
        category_title: "$_id.categories.title",
    },
    title: {$first: '$_id.category_title'},
    subcategories: {$push: '$subcategories' }
  }},
  {$project: { categories: {title: '$title', subcategories: '$subcategories'}}},
  {$group: 
    {
    _id: '$_id._id',
    card: {$first: '$_id.card'},
    name: {$first: '$_id.name'},
    report_date: {$first: '$_id.report_date'},
    categories: {$push: '$categories' }
  }},
]).pretty()

预期结果:

{
        "_id" : ObjectId("5d3361d92a38c86359f51eea"),
        "card" : "4580...",
        "name" : "John Doe",
        "report_date" : ISODate("2019-06-01T00:00:00Z"),
        "categories" : [
                {
                        "title" : "Class 1",
                        "subcategories" : [
                                {
                                        "transactions" : [
                                                {
                                                        "purchase_date" : ISODate("2019-05-14T00:00:00Z"),
                                                        "business_name" : "Restaurant",
                                                        "original_amount" : 23,
                                                        "original_currency" : "$",
                                                        "final_amount" : 23,
                                                        "final_currency" : "$",
                                                        "id" : "02201022",
                                                        "details" : "",
                                                        "expected": []
                                                },
                                                {
                                                        "purchase_date" : ISODate("2019-05-17T00:00:00Z"),
                                                        "business_name" : "Flower shop",
                                                        "original_amount" : 30,
                                                        "original_currency" : "$",
                                                        "final_amount" : 30,
                                                        "final_currency" : "$",
                                                        "id" : "4903871",
                                                        "details" : "",
                                                        "expected": []
                                                }
                                        ],
                                        "sum" : {
                                                "original_amount" : 53,
                                                "final_amount" : 53,
                                                "original_currency" : "$",
                                                "final_currency" : "$",
                                                "date" : ISODate("2019-06-01T00:00:00Z")
                                        }
                                },
                                {
                                        "transactions" : [
                                                {
                                                        "purchase_date" : ISODate("2019-05-25T00:00:00Z"),
                                                        "business_name" : "Cash withdrawal",
                                                        "original_amount" : 100,
                                                        "original_currency" : "$",
                                                        "final_amount" : 100,
                                                        "final_currency" : "$",
                                                        "id" : "0120070",
                                                        "details" : "",
                                                        expected: [
                                                            {
                                                                "_id": ObjectId("5d43396264ae143ae41bf34f"),
                                                                "card": "4580...",
                                                                "date": ISODate("2019-05-25T00:00:00Z"),
                                                                "business_name": "Cash withdrawal",
                                                                currency: "$",
                                                                owner: "John Doe"
                                                            }
                                                        ]
                                                }
                                        ],
                                        "sum" : {
                                                "original_amount" : 100,
                                                "final_amount" : 100,
                                                "original_currency" : "$",
                                                "final_currency" : "$",
                                                "date" : ISODate("2019-05-26T00:00:00Z")
                                        }
                                }
                        ]
                }
        ]
}

(我知道当前结果只是重复了报告中已经存在的信息,但将来不会如此)

谢谢!

0 个答案:

没有答案