我對 MongoDB 很陌生,第一次在大型應用程式上使用它。我們有一個復雜的嵌套結構來表示一個物件,該物件具有與其關聯的多個檔案,以及與每個檔案關聯的多個人。出于 GUI 構建的目的,我需要從檔案層次結構中提取和連接一些資訊并將其“提升”到頂層,從而創建一個簡單的平面結構。如果每個嵌套的“子查詢”有多個結果,我只對第一個感興趣。
我曾嘗試使用聚合構建器來實作這一點,但每次我最終都會有超過一百行無休止的展開、添加欄位、專案,并且它變得太長和太復雜(而且可能不是很快)而不可行。必須有一個更簡單的解決方案。讓我提供一個示例結構(我省略了大多數欄位,為簡潔起見只留下必要的欄位):
{
"_id": ObjectId(),
"number": "ABC-123456",
"status": "new",
"items": [
{
"_id": ObjectId(),
"name": "invoice",
"people": [
{
"first_name": "John",
"last_name": "Doe",
"active": false
},
{
"first_name": "Jane",
"last_name": "Smith",
"active": true
},
{
"first_name": "Fred",
"last_name": "Bloggs",
"active": true
}
]
},
{
"_id": ObjectId(),
"name": "unimportant_document",
"people": [
{
"first_name": "John",
"last_name": "Doe",
"active": true
}
]
},
{
"_id": ObjectId(),
"name": "order",
"people": [
{
"first_name": "Fred",
"last_name": "Bloggs",
"active": true
}
]
}
]
}
現在,我想得到類似這樣的結果:
{
"_id": "XXX",
"number": "ABC-123456",
"status": "new",
"invoice_person_full_name": "Jane Smith",
"order_person_full_name": "Fred Bloggs"
}
基本上,我需要將第一個人的“first_name”和“last_name”與“active”連接起來:在具有特定名稱的檔案中的一組人中為true(“invoice”代表“invoice_person_full_name”,“order”代表“o??rder_person_full_name” )。
我不關心重復,例如,如果有多個名為“發票”的檔案,我只想檢索該發票的第一張發票和第一個活躍人。
正如我所說,我已經嘗試使用聚合構建器來執行此操作,使用帶有過濾器的專案將專案陣列過濾為僅“發票”名稱,然后展開,再次投影過濾人員,再次投影以獲得第一個,展開,添加欄位,撰寫JS函式來連接名稱(實際上有度數,中間名等需要用空格分隔并且可能為空,因此 $concat 是不夠的)并最終回傳。這需要 40 多行代碼,并且僅適用于單個專案名稱,因此我需要多次組合以獲得我需要的所有名稱的結果。這可能意味著我沒有以正確的方式解決問題。
我希望我的問題足夠清楚,任何幫助將不勝感激!
uj5u.com熱心網友回復:
$set1.1。- 通過從陣列中獲取其為“發票”
invoice_persons的第一個檔案來創建欄位。itemsname1.2.
order_persons- 通過從陣列中獲取第一個檔案來創建欄位items,它name是“訂單”。$set2.1。
invoice_person_full_name- 首先過濾invoice_persons.people其所在active的檔案true。接下來是$map對全名執行字串連接。最后,獲取第一個檔案。2.2.
order_person_full_name- 首先過濾order_persons.people其所在active的檔案true。接下來是$map對全名執行字串連接。最后,獲取第一個檔案。$unset- 洗掉欄位。
db.collection.aggregate([
{
$set: {
"invoice_persons": {
$first: {
$filter: {
input: "$items",
cond: {
$eq: [
"$$this.name",
"invoice"
]
}
}
}
},
"order_persons": {
$first: {
$filter: {
input: "$items",
cond: {
$eq: [
"$$this.name",
"order"
]
}
}
}
}
}
},
{
$set: {
"invoice_person_full_name": {
$first: {
$map: {
input: {
$filter: {
input: "$invoice_persons.people",
cond: {
$eq: [
"$$this.active",
true
]
}
}
},
in: {
"$concat": [
"$$this.first_name",
" ",
"$$this.last_name"
]
}
}
}
},
"order_person_full_name": {
$first: {
$map: {
input: {
$filter: {
input: "$order_persons.people",
cond: {
$eq: [
"$$this.active",
true
]
}
}
},
in: {
"$concat": [
"$$this.first_name",
" ",
"$$this.last_name"
]
}
}
}
}
}
},
{
"$unset": [
"invoice_persons",
"order_persons",
"items"
]
}
])
示例 Mongo Playground
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/470076.html
下一篇:在Mongo中,如果我正在保存“Prateek”的檔案,那么我不希望在下一次創建操作中即使保存“prateek”或“praTEEK”等
