英文:
MongoDB join two complex collection
问题
我有两个集合
- data
{
_id: ObjectId('123'),
uuid: '123abc'
content: 'hello'
}
{
_id: ObjectId('456'),
uuid: '123abc'
content: 'hi'
}
- history
{
_id: ObjectId('xxx'),
uuid: '123abc'
data: [{path: '/hello.json', objectId: '123'}, {path: '/hi.json', objectId: '456'}]
}
我想要
{
_id: ObjectId('123'),
uuid: '123abc'
content: 'hello'
path: '/hello.json'
}
{
_id: ObjectId('456'),
uuid: '123abc'
content: 'hi'
path: '/hi.json'
}
步骤:
- 使用 uuid 查找第二个 JSON
- 使用第二个 JSON 数据数组元素的 objectId 定位第一个 JSON
是否有人知道如何编写 MongoDB 操作以连接这两个集合?
英文:
I got two collections
- data
{
_id: ObjectId('123'),
uuid: '123abc'
content: 'hello'
}
{
_id: ObjectId('456'),
uuid: '123abc'
content: 'hi'
}
- history
{
_id: ObjectId('xxx'),
uuid: '123abc'
data: [{path: '/hello.json', objectId: '123'}, {path: '/hi.json', objectId: '456'}]
}
I want
{
_id: ObjectId('123'),
uuid: '123abc'
content: 'hello'
path: '/hello.json'
}
{
_id: ObjectId('456'),
uuid: '123abc'
content: 'hi'
path: '/hi.json'
}
Step:
- use the uuid to find the second json
- use the objectId of the second json data array element to locate the first json
Does anyone who knows how to write the MongoDB operations to join the two collections
答案1
得分: 1
你可以使用聚合框架来实现:
$lookup
- 从 history 集合中获取数据- 使用
$set
和$first
- 从history
属性中获取第一个元素,因为$lookup
总是返回一个数组 - 使用
$set
和$filter
- 创建一个path_element
属性,其中包含基于文档_id
进行筛选的历史记录 $project
- 以期望的输出形式投影数据。
db.data.aggregate([
{
"$lookup": {
"from": "history",
"localField": "uuid",
"foreignField": "uuid",
"as": "history"
}
},
{
"$set": {
"history": {
"$first": "$history"
}
}
},
{
$set: {
path_element: {
"$filter": {
"input": "$history.data",
"cond": {
$eq: [
{
$toString: "$_id"
},
"$$this.objectId"
]
}
}
}
}
},
{
$project: {
_id: 1,
uuid: 1,
content: 1,
path: {
"$getField": {
"field": "path",
"input": {
$first: "$path_element"
}
}
}
}
}
])
英文:
You can do it with Aggregation Framework:
$lookup
- To fetch data from the history collection$set
with$first
- To get the first element from thehistory
property, since the$lookup
always return an array$set
with$filter
- To create apath_element
property that has the filtered history based on the document_id
.$project
- to project the data as expected output.
db.data.aggregate([
{
"$lookup": {
"from": "history",
"localField": "uuid",
"foreignField": "uuid",
"as": "history"
}
},
{
"$set": {
"history": {
"$first": "$history"
}
}
},
{
$set: {
path_element: {
"$filter": {
"input": "$history.data",
"cond": {
$eq: [
{
$toString: "$_id"
},
"$$this.objectId"
]
}
}
}
}
},
{
$project: {
_id: 1,
uuid: 1,
content: 1,
path: {
"$getField": {
"field": "path",
"input": {
$first: "$path_element"
}
}
}
}
}
])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论