mongodb - 如何在嵌套的对象数组中查找 $lookup
问题描述
我必须有两个集合,一个是旅游,另一个是目的地,所以在旅游中我有一个位置数组,其中有一个带有 id 的目标对象,并且该 id 属于另一个目的地集合,但问题是我无法查找详细信息位置数组中的目的地。每一个在这里也尝试了很多查询搜索。但没有得到预期的结果。
旅游:
{
"_id" : ObjectId("5f3122f4d8d57e3b9650e5b4"),
"title" : "tour 1",
"locations" : [
{
"destination" : {
"id" : "5ec5ae9037ea99f20a79071a"
},
"services" : {
"hotel" : true
}
},
{
"destination" : {
"id" : "5ec5ae8e37ea99f20a78ef8c"
},
"services" : {
"hotel" : true
}
}
]
}
{
"_id" : ObjectId("5f2d65e68bc6e9155310d147"),
"title" : "tour 2",
"locations" : [
{
"destination" : {
"id" : "5ecf994435c3a6025d5bf126"
},
"services" : {
"hotel" : true
}
}
]
}
{
"_id" : ObjectId("5f2d66398bc6e9155310d161"),
"title" : "tour 3",
"locations" : [
{
"destination" : {
"id" : "5ec5ae8e37ea99f20a78ef8d"
},
"services" : {
"hotel" : true
}
}
]
}
目的地:
{
"_id" : ObjectId("5ec5ae9037ea99f20a79071a"),
"name" : "dest 1",
"country" : "country name"
}
{
"_id" : ObjectId("5ec5ae8e37ea99f20a78ef8c"),
"name" : "dest 2",
"country" : "country name"
}
{
"_id" : ObjectId("5ec5ae8e37ea99f20a78ef8d"),
"name" : "dest 3",
"country" : "country name"
}
{
"_id" : ObjectId("5ecf994435c3a6025d5bf126"),
"name" : "dest 4",
"country" : "country name"
}
预期结果 :
{
"_id" : ObjectId("5f3122f4d8d57e3b9650e5b4"),
"title" : "tour 1",
"locations" : [
{
"destination" : {
"id" : "5ec5ae9037ea99f20a79071a",
"name" : "dest 1",
"country" : "country name"
},
"services" : {
"hotel" : true
}
},
{
"destination" : {
"id" : "5ec5ae8e37ea99f20a78ef8c",
"name" : "dest 2",
"country" : "country name"
},
"services" : {
"hotel" : true
}
}
]
},
{
"_id" : ObjectId("5f2d65e68bc6e9155310d147"),
"title" : "tour 2",
"locations" : [
{
"destination" : {
"id" : "5ecf994435c3a6025d5bf126",
"name" : "dest 4",
"country" : "country name"
},
"services" : {
"hotel" : true
}
}
]
},
{
"_id" : ObjectId("5f2d66398bc6e9155310d161"),
"title" : "tour 3",
"locations" : [
{
"destination" : {
"id" : "5ec5ae8e37ea99f20a78ef8d",
"name" : "dest 3",
"country" : "country name"
},
"services" : {
"hotel" : true
}
}
]
}
尝试查询:
db.tours.aggregate([
{
"$addFields": {
"locations": {
"$map": {
"input": "$locations",
"in": {
"$mergeObjects": [
"$$this",
{
"dest_oid": {
"$toObjectId": "$$this.destination.id"
}
}
]
}
}
}
}
},
{ "$unwind": "$locations" },
{ "$lookup": {
"from": "destinations",
"localField": "locations.dest_oid",
"foreignField": "_id",
"as": "locations.dest",
}},
{ "$unwind": "$locations.dest" },
{ "$group": {
"_id": "$_id",
"locations": { "$push": "$locations" }
}}
])
解决方案
快速修复,
$unwind
locations
数组放在第一位,因为需要将 id 转换为对象 id
db.tours.aggregate([
{ $unwind: "$locations" },
- 如果您已经转换了字符串 id t 对象 id,则跳过这部分
$addFields
替换locations.destination.id
为对象 id 将您的逻辑过滤为简短,这里不需要 $map 和 $mergeObjects 选项
{
$addFields: {
"locations.destination.id": {
$toObjectId: "$locations.destination.id"
}
}
},
$lookup
你已经做了,但改变为locations.destination
{
$lookup: {
from: "destinations",
as: "locations.destination",
localField: "locations.destination.id",
foreignField: "_id"
}
},
- $unwind
locations.destination
因为它的数组,我们需要对象
{
$unwind: {
path: "$locations.destination"
}
},
$group
您已经做过的,少量更改,在位置推送第一个目的地和服务并添加第一个标题
{
$group: {
_id: "$_id",
locations: { $push: "$locations" },
title: { $first: "$title" }
}
}
])
推荐阅读
- java - 保存单向一对一子实体时分离的持久化父实体
- javascript - 嵌套数组递归 - NodeJS
- unix - 在 z/OS UNIX 文件中替换十六进制字符
- android - 程序类型已存在:com.google.android.gms.actions.ItemListIntents
- php - SQL 查询在 phpmyadmin 中工作,但不在 PHP 脚本中
- google-chrome - 在 chrome 中从 DevTools 中选择样式数据
- python - PyCharm 无法解析多处理模块的动态引用
- selenium - 如何移动到删除按钮并在 Selenium 中单击该按钮?
- c# - mongodb c# addShardTag
- php - 无法为模块 DBD::Oracle: libclntsh.so.12.1 加载“/usr/local/lib64/perl5/auto/DBD/Oracle/Oracle.so”