MongoDB 仅查找某些值
MongoDB lookup only on certain values
我有以下数据库数据和查询:https://mongoplayground.net/p/8jx-oejWQV7.
我正在尝试仅对 questions.value
类型的 ObjectId 执行查找。并希望查询中的 return 看起来像这样:
[
{
"_id": ObjectId("60d9c9ff7fde704f28e89040"),
"questions": [
{
"id": "607569f06df0a80197227d06",
"value": "A String Value 1"
},
{
"id": "607569f78f403f67dd1fefed",
"value": "A String value 2"
},
{
"id": "607569f78f403f67dd1fefef",
"value": "A String value 3"
},
{
"id": "607569e0701e55c65eae7554",
"value": "C"
},
{
"id": "607569e86b5b2a2175cce0f0",
"value": "C"
},
{
"id": "607569fff2597be5ff2444fd",
"value": "B"
},
{
"id": "607569fff2597be5ff2444fc",
"value": "A"
}
]
}
]
我该如何重新添加非 'looked up' 值?
谢谢!
在您的查询中,问题与 $unwind
有关,因此您删除了空数组值。
您需要使用 $ifNull
更新您的查询以保留初始数组中的值,但一般答案是 您需要使用 preserveNullAndEmptyArrays
...
{
$project: {
"questions.id": 1,
"questions.value": "$questions.value.displayLabel"
}
},
{
$unwind: {
path: "$questions.value",
preserveNullAndEmptyArrays: true
}
},
您需要更正您的查询,
$unwind
- 按原样放置
$lookup
- 按原样放置,但将 as
字段重命名为 refValue
$addFields
检查条件,如果结果为空数组,则保持相同的值,否则使用 $first
运算符 替换为查找值
$unset
删除 refValue
现在不需要
$group
- 按原样放置但添加 status
字段
db.products.aggregate([
{ $unwind: "$questions" },
{
$lookup: {
from: "ex_ref_data",
let: { questionValue: "$questions.value" },
pipeline: [
{ $match: { $expr: { $eq: ["$$questionValue", "$_id"] } } },
{
$project: {
displayLabel: 1,
_id: 0
}
}
],
as: "questions.refValue"
}
},
{
$addFields: {
"questions.value": {
$cond: [
{ $ne: ["$questions.refValue", []] },
{ $first: "$questions.refValue.displayLabel" },
"$questions.value"
]
}
}
},
{ $unset: "questions.refValue" },
{
$group: {
_id: "$_id",
status: { $first: "$status" },
questions: { $push: "$questions" }
}
}
])
第二个选项,您可以使用下面的方法而不使用 $unwind
和 $group
阶段,
$project
显示必填字段
$type
获取 value
的数据类型
$filter
迭代 questions
的循环并通过 type
过滤到 select 只有具有“objectId”元素的值
$filter
迭代 questions
的循环并通过 type
过滤到 select 只有 none “obejctId” 元素
$lookup
与管道,let
传递参考值并检查 $in
条件,以及 return _id
和 value
字段
- $addFields 使用
$map
、$filter
和 $mergeObjects
将当前问题与查找结果问题值连接起来
$unset
删除不需要的字段
$concatArrays
将引用数组和非引用数组合并为一个
db.products.aggregate([
{
$project: {
status: 1,
ref: {
$filter: {
input: "$questions",
cond: { $eq: [{ $type: "$$this.value" }, "objectId"] }
}
},
nonRef: {
$filter: {
input: "$questions",
cond: { $ne: [{ $type: "$$this.value" }, "objectId"] }
}
}
}
},
{
$lookup: {
from: "ex_ref_data",
let: { questionValue: "$ref.value" },
pipeline: [
{ $match: { $expr: { $in: ["$_id", "$$questionValue"] } } },
{ $project: { value: "$displayLabel" } }
],
as: "ref"
}
},
{
$addFields: {
ref: {
$map: {
input: "$ref",
as: "r",
in: {
$mergeObjects: [
"$$r",
{
$first: {
$filter: {
input: "$refResult",
cond: { $eq: ["$$this._id", "$$r.value"] }
}
}
}
]
}
}
}
}
},
{ $unset: "ref._id" },
{
$project: {
status: 1,
questions: { $concatArrays: ["$nonRef", "$ref"] }
}
}
])
我有以下数据库数据和查询:https://mongoplayground.net/p/8jx-oejWQV7.
我正在尝试仅对 questions.value
类型的 ObjectId 执行查找。并希望查询中的 return 看起来像这样:
[
{
"_id": ObjectId("60d9c9ff7fde704f28e89040"),
"questions": [
{
"id": "607569f06df0a80197227d06",
"value": "A String Value 1"
},
{
"id": "607569f78f403f67dd1fefed",
"value": "A String value 2"
},
{
"id": "607569f78f403f67dd1fefef",
"value": "A String value 3"
},
{
"id": "607569e0701e55c65eae7554",
"value": "C"
},
{
"id": "607569e86b5b2a2175cce0f0",
"value": "C"
},
{
"id": "607569fff2597be5ff2444fd",
"value": "B"
},
{
"id": "607569fff2597be5ff2444fc",
"value": "A"
}
]
}
]
我该如何重新添加非 'looked up' 值?
谢谢!
在您的查询中,问题与 $unwind
有关,因此您删除了空数组值。
您需要使用 $ifNull
更新您的查询以保留初始数组中的值,但一般答案是 您需要使用 preserveNullAndEmptyArrays
...
{
$project: {
"questions.id": 1,
"questions.value": "$questions.value.displayLabel"
}
},
{
$unwind: {
path: "$questions.value",
preserveNullAndEmptyArrays: true
}
},
您需要更正您的查询,
$unwind
- 按原样放置$lookup
- 按原样放置,但将as
字段重命名为refValue
$addFields
检查条件,如果结果为空数组,则保持相同的值,否则使用$first
运算符 替换为查找值
$unset
删除refValue
现在不需要$group
- 按原样放置但添加status
字段
db.products.aggregate([
{ $unwind: "$questions" },
{
$lookup: {
from: "ex_ref_data",
let: { questionValue: "$questions.value" },
pipeline: [
{ $match: { $expr: { $eq: ["$$questionValue", "$_id"] } } },
{
$project: {
displayLabel: 1,
_id: 0
}
}
],
as: "questions.refValue"
}
},
{
$addFields: {
"questions.value": {
$cond: [
{ $ne: ["$questions.refValue", []] },
{ $first: "$questions.refValue.displayLabel" },
"$questions.value"
]
}
}
},
{ $unset: "questions.refValue" },
{
$group: {
_id: "$_id",
status: { $first: "$status" },
questions: { $push: "$questions" }
}
}
])
第二个选项,您可以使用下面的方法而不使用 $unwind
和 $group
阶段,
$project
显示必填字段$type
获取value
的数据类型
$filter
迭代questions
的循环并通过type
过滤到 select 只有具有“objectId”元素的值$filter
迭代questions
的循环并通过type
过滤到 select 只有 none “obejctId” 元素$lookup
与管道,let
传递参考值并检查$in
条件,以及 return_id
和value
字段- $addFields 使用
$map
、$filter
和$mergeObjects
将当前问题与查找结果问题值连接起来
$unset
删除不需要的字段$concatArrays
将引用数组和非引用数组合并为一个
db.products.aggregate([
{
$project: {
status: 1,
ref: {
$filter: {
input: "$questions",
cond: { $eq: [{ $type: "$$this.value" }, "objectId"] }
}
},
nonRef: {
$filter: {
input: "$questions",
cond: { $ne: [{ $type: "$$this.value" }, "objectId"] }
}
}
}
},
{
$lookup: {
from: "ex_ref_data",
let: { questionValue: "$ref.value" },
pipeline: [
{ $match: { $expr: { $in: ["$_id", "$$questionValue"] } } },
{ $project: { value: "$displayLabel" } }
],
as: "ref"
}
},
{
$addFields: {
ref: {
$map: {
input: "$ref",
as: "r",
in: {
$mergeObjects: [
"$$r",
{
$first: {
$filter: {
input: "$refResult",
cond: { $eq: ["$$this._id", "$$r.value"] }
}
}
}
]
}
}
}
}
},
{ $unset: "ref._id" },
{
$project: {
status: 1,
questions: { $concatArrays: ["$nonRef", "$ref"] }
}
}
])