英文:
mongodb multiple collection join with groupby
问题
以下是你提供的内容的翻译:
我是MongoDB的新手,但我正在尝试根据文档类型(type_id)聚合数据。我有以下集合。
items集合
{
"_id": "BE05332051E0AD282",
"type_id": "684EB00155D031225", //组织或书籍或个人
"name": "Owi Student Union",
"structure": {
"organization_active_status": "Inactive",
"country": "USA"
},
"hash": "59E48A8C3F7B20",
"geometry": {
"type": "Point",
"coordinates": [
-85.48172999999997,
32.60746000000006
]
},
"geometry_confidence": 0.0,
"has_geometry": true,
"is_node": false,
"groupids": [
"DE05332041E0A4978"
]
}
tuples集合
{
"_id": "0E05333051E0A02E7",
"source_id": "BE05332051E0AD282",
"destination_id": "9E05332051E0AF344",
"edge_id": "DE05332051E0A3B5B",
"direction": NumberInt(1),
"changed": true
}
{
"_id": "0E05333061E0A02E8",
"source_id": "BE05332051E0AD282",
"destination_id": "0E05333051E0A02E7",
"edge_id": "DE05332051E0A3B5B",
"direction": NumberInt(1),
"changed": true
}
types集合
{
"_id": "684EB00155D031225",
"name": "Organization"
}
{
"_id": "BE0532A041E0AC077",
"name": "Book"
}
1)items集合包含所有类型的文档,包括组织、书籍,可以根据type_id进行区分。
2)每个组织可能有多本书籍和个人。
关系:
1)tuples.source_id = items._id
2)tuples.destination_id = items._id
3)items.type_id = type._id
我正在尝试像这样聚合数据,但无法获得完整的结果。
db.tuples.aggregate([
{
$lookup: {
from: "items",
localField: "destination_id",
foreignField: "_id",
as: "source"
}
},
{
$match: {
"source_id": "5BD5A377499D406EE05332051E0A93C2",
"source.type_id": "43B369EDE96A4876E0532A041E0A995A"
}
}
]);
有人可以帮助我如何创建最终结果,类似于以下内容:
组织
{
"_id": "BE05332051E0AD282",
"type_id": "684EB00155D031225", //组织
"chapters": {
"章节列表(从item集合中获取的文档)"
},
"books": {
"书籍列表(从item集合中获取的文档)"
}
}
我真的很感谢任何形式的帮助或建议,谢谢!
英文:
I am noobie in mongodb,
<br>but I am trying to aggregate data based on type of document(type_id)
I have following collections
items<br>
{
"_id" : "BE05332051E0AD282",
"type_id" : "684EB00155D031225",//Organization or Book or Person
"name" : "Owi Student Union",
"structure" : {
"organization_active_status" : "Inactive",
"country" : "USA"
},
"hash" : "59E48A8C3F7B20",
"geometry" : {
"type" : "Point",
"coordinates" : [
-85.48172999999997,
32.60746000000006
]
},
"geometry_confidence" : 0.0,
"has_geometry" : true,
"is_node" : false,
"groupids" : [
"DE05332041E0A4978"
]
}
tuples<br>
{
"_id" : "0E05333051E0A02E7",
"source_id" : "BE05332051E0AD282",
"destination_id" : "9E05332051E0AF344",
"edge_id" : "DE05332051E0A3B5B",
"direction" : NumberInt(1),
"changed" : true
}
{
"_id" : "0E05333061E0A02E8",
"source_id" : "BE05332051E0AD282",
"destination_id" : "0E05333051E0A02E7",
"edge_id" : "DE05332051E0A3B5B",
"direction" : NumberInt(1),
"changed" : true
}
types<br>
{
"_id" : "684EB00155D031225",
"name" : "Organization"
},
{
"_id" : "BE0532A041E0AC077",
"name" : "Book"
}
- items collection contain all type of document for organization, books and can be differentiate on type_id
- each organizations may have multiple books, person
relations
1) tuples.source_id = items._id
2) tuples.destination_id = items._id
3) items.type_id = type._id
I am trying aggregate data like this, but unable to get complete result
db.tuples.aggregate([
{
$lookup:{
from: "items",
localField: "destination_id",
foreignField: "_id",
as: "source"
}
},
{
$match:{
"source_id":"5BD5A377499D406EE05332051E0A93C2",
"source.type_id" : "43B369EDE96A4876E0532A041E0A995A"
}
}
]);
Could any one help me on how can I create final result like this
Organizations
{
"_id" : "BE05332051E0AD282",
"type_id" : "684EB00155D031225",//Organization
chapters : {
"list of chapter(documents from item collection)"
},
books : {
"list of books(documents from item collection)"
}
}
I would really appreciate any kind of help or suggestion, Thanks
答案1
得分: 1
你可以使用以下聚合管道来实现这个功能。你可以在这里运行它,
https://mongoplayground.net/p/H2Ygqgjp2f5
db.items.aggregate([
{
"$match": {
"type_id": "684EB00155D031225"
}
},
{
"$lookup": {
from: "tuples",
localField: "_id",
foreignField: "source_id",
as: "tuples"
}
},
{
"$lookup": {
from: "items",
let: {
destination_ids: "$tuples.destination_id"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$destination_ids"
]
},
"type_id": "BE0532A041E0AC077"
}
}
],
as: "books"
}
},
{
"$lookup": {
from: "items",
let: {
destination_ids: "$tuples.destination_id"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$destination_ids"
]
},
"type_id": "BE0532A041E0AC087"
}
}
],
as: "persons"
}
},
{
"$project": {
"_id": 1,
"type_id": 1,
"name": 1,
"books": 1,
"persons": 1
}
}
])
这将返回如下结果。
[
{
"_id": "BE05332051E0AD282",
"books": [
{
"_id": "9E05332051E0AF344",
"name": "Test Book 1",
"type_id": "BE0532A041E0AC077"
}
],
"name": "Owi Student Union",
"persons": [
{
"_id": "0E05333051E0A02E7",
"name": "Test Person 1",
"type_id": "BE0532A041E0AC087"
}
],
"type_id": "684EB00155D031225"
}
]
但我建议您重新考虑您的数据库设计,因为您正在使用NoSQL数据库,您应该能够嵌入文档并拥有类似树结构的结构。希望这有所帮助。
英文:
You can achieve this with aggregation pipeline as below. You can run it here,
https://mongoplayground.net/p/H2Ygqgjp2f5
db.items.aggregate([
{
"$match": {
"type_id": "684EB00155D031225"
}
},
{
"$lookup": {
from: "tuples",
localField: "_id",
foreignField: "source_id",
as: "tuples"
}
},
{
"$lookup": {
from: "items",
let: {
destination_ids: "$tuples.destination_id"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$destination_ids"
]
},
"type_id": "BE0532A041E0AC077"
}
}
],
as: "books"
}
},
{
"$lookup": {
from: "items",
let: {
destination_ids: "$tuples.destination_id"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$destination_ids"
]
},
"type_id": "BE0532A041E0AC087"
}
}
],
as: "persons"
}
},
{
"$project": {
"_id": 1,
"type_id": 1,
"name": 1,
"books": 1,
"persons": 1
}
}
])
this would return a result as this.
[
{
"_id": "BE05332051E0AD282",
"books": [
{
"_id": "9E05332051E0AF344",
"name": "Test Book 1",
"type_id": "BE0532A041E0AC077"
}
],
"name": "Owi Student Union",
"persons": [
{
"_id": "0E05333051E0A02E7",
"name": "Test Person 1",
"type_id": "BE0532A041E0AC087"
}
],
"type_id": "684EB00155D031225"
}
]
But I would suggest you rethink your database design, since you are using a nosql database you should be able to embed documents and have a tree like structure. Hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论