游乐场链接: 蒙戈游乐场
我想得到以下查询结果。
一张与
filters
开始匹配的卡片,它以字符串数组开始,以来自 filters 集合的新对象结束。
filters 集合有一个带有
enabled
和 archived
字段的主过滤器以及子过滤器列表。 CARD 过滤器 [string]
列表只会有子过滤器字符串值启动,但这些值可能来自多个主过滤器列表(子过滤器值)。
"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
}
]
}
]
例如,在上面的数据集中,一张卡片可能有一个以
filters
开头的 ['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"
}
}
])