【发布时间】:2020-10-12 02:28:17
【问题描述】:
抱歉标题不好,但这是我要解决的问题:
我有几个集合,包括票证、字段和 fieldOptions,它们看起来像这样:
门票:
{
_id: 1,
subject: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
fields: [
{
key: "part-number",
value: "abc123",
},
{
key: "price",
value: "10",
},
{
key: "officer",
value: "2",
},
]
}
字段:
[
{
_id: 1,
created: ISODate("2020-09-10T20:23:46.382Z"),
options: [],
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
displayOrder: 0,
key: "part-number",
label: "Part Number",
required: false,
type: "text",
},
{
_id: 2,
created: ISODate("2020-09-10T20:23:46.382Z"),
options: [],
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
displayOrder: 1,
key: "price",
label: "Price",
required: false,
type: "text",
},
{
_id: 3,
created: ISODate("2020-09-10T20:23:46.382Z"),
options: [1, 2, 3, 4],
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
displayOrder: 2,
key: "officer",
label: "Officer",
required: false,
type: "select",
},
// THIS WAS ADDED AFTER THE 'TICKET' DOC WAS CREATED, SO IT'S NOT LISTED UNDER 'FIELDS' IN THERE
{
_id: 4,
created: ISODate("2020-09-10T20:23:46.382Z"),
options: [],
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
displayOrder: 1,
key: "notes",
label: "Notes",
required: false,
type: "text",
},
]
字段选项:
[
{
_id: 1,
created: ISODate("2020-09-10T20:23:46.382Z"),
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
key: "none",
label: "None",
displayOrder: 0,
legacy: false,
},
{
_id: 2,
created: ISODate("2020-09-10T20:23:46.382Z"),
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
key: "picard",
label: "Picard",
displayOrder: 1,
legacy: false,
},
{
_id: 3,
created: ISODate("2020-09-10T20:23:46.382Z"),
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
key: "riker",
label: "Riker",
displayOrder: 2,
legacy: false,
},
{
_id: 4,
created: ISODate("2020-09-10T20:23:46.382Z"),
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
key: "data",
label: "Data",
displayOrder: 3,
legacy: false,
},
{
_id: 5,
created: ISODate("2020-09-10T20:23:46.382Z"),
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
key: "red-shirt",
label: "Red Shirt",
displayOrder: 4,
legacy: true,
},
]
在我的聚合管道中,我有以下内容:
[
{ $match: {_id: 2} },
{ $unwind: { path: "$fields", "preserveNullAndEmptyArrays": true } },
{
"$lookup": {
"from": "fields",
"let": { "key": "$fields.key" },
"as": "fields.def",
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$key", "$$key"] } } },
{
"$lookup": {
"from": "fieldoptions",
"let": { "options": "$options" },
"pipeline": [
{ "$match": { "$expr": { "$in": ["$_id", "$$options"] } } },
],
"as": "options"
}
}
]
}
},
{ $unwind: { path: "$fields.def", "preserveNullAndEmptyArrays": true } },
{
$group: {
_id: "$_id",
fields: { $push: "$$ROOT.fields" },
root: { $mergeObjects: "$$ROOT" },
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: ["$root", "$$ROOT"]
}
}
},
{
$unset: "root"
},
{ $project: { fields: '$fields'}} // this is to remove other junk for testing
]
这带来了以下(几乎正确的)结果:
{
"_id" : 2,
"fields" : [
{
"key" : "part-number",
"value" : "abc123",
"def" : {
"_id" : 1,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"options" : [],
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"displayOrder" : 0,
"key" : "part-number",
"label" : "Part Number",
"required" : false,
"type" : "text",
"__v" : 0
}
},
{
"key" : "price",
"value" : "10",
"def" : {
"_id" : 2,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"options" : [],
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"displayOrder" : 1,
"key" : "price",
"label" : "Price",
"required" : false,
"type" : "text",
"__v" : 0
}
},
{
"key" : "officer",
"value" : "2",
"def" : {
"_id" : 3,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"options" : [
{
"_id" : 1,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"key" : "none",
"label" : "None",
"displayOrder" : 0,
"legacy" : false,
"__v" : 0
},
{
"_id" : 2,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"key" : "picard",
"label" : "Picard",
"displayOrder" : 1,
"legacy" : false,
"__v" : 0
},
{
"_id" : 3,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"key" : "riker",
"label" : "Riker",
"displayOrder" : 2,
"legacy" : false,
"__v" : 0
},
{
"_id" : 4,
"created" : ISODate("2020-09-10T20:23:46.382Z"),
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"key" : "data",
"label" : "Data",
"displayOrder" : 3,
"legacy" : false,
"__v" : 0
}
],
"updated" : ISODate("2020-09-10T20:23:46.382Z"),
"active" : true,
"displayOrder" : 2,
"key" : "officer",
"label" : "Officer",
"required" : false,
"type" : "select",
"__v" : 0
}
}
]
}
我的问题是,如果我在“字段”集合中添加一些东西(我们称之为属性“foo”),现有的票证对象没有“foo”引用,因此它不会出现在票证对象中,我想以某种方式(在聚合框架中)获取当前字段的列表,并为每个查找对应的值(如果存在),否则返回一个空值,如下所示:
新票结果:
{
_id: 2,
fields: [
... //existing fields
{
key: "foo", // <-- new fields / fields not listed on the ticket
value: null,
def: {
_id: 1,
created: ISODate("2020-09-10T20:23:46.382Z"),
options: [],
updated: ISODate("2020-09-10T20:23:46.382Z"),
active: true,
displayOrder: 0,
key: "foo",
label: "Foo",
required: false,
type: "text",
__v: 0,
},
},
],
}
如何做到这一点?另外,有没有比我有更好的方法来做到这一点?我对聚合还很陌生,还在尝试。
【问题讨论】:
-
您认为提供的答案中是否有某些内容无法解决您的问题?如果是这样,那么请对答案发表评论,以阐明究竟需要解决哪些尚未解决的问题。
标签: mongodb aggregation