我最近第一次开始使用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”的一系列匹配项。 查询条件:
以下查询有效,但如上所述,我认为它太复杂了:
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")
}
}
]
}
]
}
(我知道当前结果只是重复了报告中已经存在的信息,但将来不会如此)
谢谢!