游乐场链接 蒙戈游乐场
我想得到以下查询结果。
与起始匹配匹配的一张卡,其中 card.filters 以字符串数组开头,以过滤器集合中的新对象结束。
过滤器集合具有已启用的主过滤器、存档字段和子过滤器列表。 CARD 过滤器 [字符串] 列表将仅具有要启动的子过滤器字符串值,但这些值可能来自多个主过滤器列表(子过滤器值)。
"cards": [
{
"cardId": "one-two-three",
"filters": [
"one",
"two",
"five"
]
}
],
"filters": [
{
"label": "filter-one-primary",
"enabled": true,
"archived": false,
"list": [
{
"label": "One",
"value": "one",
"disabled": false
},
{
"label": "Four",
"value": "four",
"disabled": false
}
]
},
{
"label": "filter-two-primary",
"enabled": true,
"archived": false,
"list": [
{
"label": "Two",
"value": "two",
"disabled": false
},
{
"label": "Five",
"value": "five",
"disabled": false
}
]
}
]
例如在上面的数据集中,一张卡片的起始过滤器数组可能为 [‘one’, ‘two’, ‘ Five’]
我希望在管道的开始部分首先根据主过滤器对象“enabled”:true和“archived”:false以及列表是否包含任何子过滤器来选择所有需要的过滤器。所以在上面的数据集中它会选择两者。
获得过滤器后,我们需要将它们转换为第一个返回的 CARD 中的以下内容。
所以使用上面的例子,返回的 CARD 会有这个。
[
{
"_id": ObjectId("5a934e000102030405000000"),
"cardId": "one-two-three",
"filters": [
{
primary: "filter-one-primary", // Used to be from filter object.label
secondary: "One", // Used to be from filter object.[list].value
id: "one", // Used to be from filter object.[list].value
disabled: false // Used to be from filter object.[list].disabled
},
primary: "filter-two-primary", // Used to be from filter object.label
secondary: "Two", // Used to be from filter object.[list].value
id: "two", // Used to be from filter object.[list].value
disabled: false // Used to be from filter object.[list].disabled
{
},
{
primary: "filter-two-primary", // Used to be from filter object.label
secondary: "Five", // Used to be from filter object.[list].value
id: "five", // Used to be from filter object.[list].value
disabled: false // Used to be from filter object.[list].disabled
}
]
}
]
在 $lookup 管道中,我们将匹配
// DATA
db={
"cards": [
{
"cardId": "one-two-three",
"filters": [
"four",
"five",
"six"
]
}
],
"filters": [
{
"label": "filter-one-primary",
"enabled": true,
"archived": false,
"list": [
{
"label": "One",
"value": "one",
"disabled": false
},
{
"label": "Four",
"value": "four",
"disabled": false
}
]
},
{
"label": "filter-two-primary",
"enabled": true,
"archived": false,
"list": [
{
"label": "Two",
"value": "two",
"disabled": false
},
{
"label": "Five",
"value": "five",
"disabled": false
}
]
},
{
"label": "filter-three-primary",
"enabled": true,
"archived": false,
"list": [
{
"label": "Three",
"value": "three",
"disabled": false
},
{
"label": "SiX",
"value": "six",
"disabled": false
}
]
}
]
}
db.cards.aggregate([
{
$match: {
"cardId": "one-two-three"
}
},
{
$lookup: {
from: "filters",
"let": {
"id": "filters"
},
pipeline: [
{
$match: {
$and: [
{
$expr: {
$in: [
"$$id",
"$list.value"
]
},
"enabled": true,
"archived": false
}
]
}
}
],
as: "filters"
}
}
])
在您的
$lookup
管道中:
$match
- 您的 $$id
是来自 filters
数组值的数组字段。因此,您不应使用 $in
运算符,而应使用 $setIntersection
、$size
运算符来检查数组之间是否存在任何相交/匹配的元素。
$unwind
- 将 list
数组解构为多个文档。
$match
- 通过匹配 list.value
来过滤文档。
$project
- 装饰要在 filters
数组中输出的文档。
db.cards.aggregate([
{
$match: {
"cardId": "one-two-three"
}
},
{
$lookup: {
from: "filters",
"let": {
"id": "$filters"
},
pipeline: [
{
$match: {
$and: [
{
$expr: {
$gt: [
{
$size: {
$setIntersection: [
"$$id",
"$list.value"
]
}
},
0
]
},
"enabled": true,
"archived": false
}
]
}
},
{
$unwind: "$list"
},
{
$match: {
$expr: {
$in: [
"$list.value",
"$$id"
]
}
}
},
{
$project: {
_id: 0,
primary: "$label",
secondary: "$list.label",
id: "$list.value",
disabled: "$list.disabled"
}
}
],
as: "filters"
}
}
])