這一篇接着記錄一下查詢相關的操做。想象一下,若是想要在一張表格中展現某些車輛的耗損和營收狀況,咱們該怎麼處理。車輛、耗損、營收各自存儲在一張表中,耗損和營收中冗餘了車輛信息……咱們便想到了關聯查詢。mongodb 3.2+中開始支持關聯查詢,下面介紹一下寫關聯查詢的過程。html
測試1、mongodb
db.getCollection('FormInstace').aggregate([ { $match: { "FormItems.key": { $ne: null } } }, { $addFields: { FormValueObj: { $arrayToObject: { $map: { input: "$FormItems", as: "field", in: [ "$$field.key", "$$field.value" ] } } } } }, { $replaceRoot: { newRoot: { $mergeObjects: [ "$FormValueObj", "$$ROOT" ] } } }, { $project: { FormItems:0, FormValueObj:0 } }, { $lookup:{ from:"FormInstace", localField:'_id', foreignField:'FormItems.value.id', as:'RelationData' } } ]);
結合前面筆記的成果和官方文檔寫了第一個關聯查詢,此次查詢跑了300s直接累死了,因而我便介紹了一下數量。數組
測試2、數據結構
db.getCollection('FormInstace').aggregate([ { $match: { "_id":{$in:["1","2","3"]}, "FormItems.key": { $ne: null } } }, { $addFields: { FormValueObj: { $arrayToObject: { $map: { input: "$FormItems", as: "field", in: [ "$$field.key", "$$field.value" ] } } } } }, { $replaceRoot: { newRoot: { $mergeObjects: [ "$FormValueObj", "$$ROOT" ] } } }, { $project: { FormItems:0, FormValueObj:0 } }, { $lookup:{ from:"FormInstace", localField:'_id', foreignField:'FormItems.value.id', as:'RelationData' } } ]);
此次總算沒有報錯,可是耗時也夠長的(十多秒);關聯數據(RelationData)確實是查出來了,可是該數組中的關聯數據仍是原來的數據結構。那麼咱們是否是一樣能夠將關聯數據中的表單項的值也放到最外層,答案是能夠的。測試
測試3、spa
db.getCollection('FormInstace').aggregate([ { $match: { "_id":{$in:["1","2","3"]}, "FormItems.key": { $ne: null } } }, { $addFields: { FormValueObj: { $arrayToObject: { $map: { input: "$FormItems", as: "field", in: [ "$$field.key", "$$field.value" ] } } } } }, { $replaceRoot: { newRoot: { $mergeObjects: [ "$FormValueObj", "$$ROOT" ] } } }, { $project: { FormItems:0, FormValueObj:0 } }, { $lookup:{ from:"FormInstace", localField:'_id', foreignField:'FormItems.value.id', as:'RelationData' } }, { $addFields:{ RelationData:{ $map: { input: "$RelationData", as: "tr", in: { $arrayToObject:{ $map: { input:{ $concatArrays: [ [ {key:"_id",value:"$$tr._id"}, {key:"ExtendData",value:"$$tr.ExtendData"}, {key:"CreateUserId",value:"$$tr.CreateUserId"}, {key:"CreateUserName",value:"$$tr.CreateUserName"}, {key:"CreateDate",value:"$$tr.CreateDate"}, {key:"LastModifyDate",value:"$$tr.LastModifyDate"}, {key:"FormId",value:"$$tr.FormId"}, {key:"FormVersion",value:"$$tr.FormVersion"}, ], "$$tr.FormItems" ] }, as: "field", in: ["$$field.key","$$field.value"] } } } } } } } ]);
這個查詢獲得了咱們想要的效果,可是這個關聯查詢太費勁了,不單是代碼一大推,而且還要處理關聯數據(RelationData)的結構……由於全部的數據都放在同一張表中,以前咱們處理過這張表,如今還要處理一遍,不太情願😔😔😔。以前不是能夠建立視圖嗎?那咱們是否是能夠用視圖關聯視圖,趕忙試試。3d
測試四(建立視圖)、code
db.getCollection('FormInstaceView').aggregate([ { $match: { "_id":{$in:["1","2","3"]} } }, { $lookup:{ from:"FormInstaceView", localField:'_id', foreignField:'1572493552001.id', as:'RelationData' } } ]);
不知道你有沒有發現視圖關聯查詢和上面的關聯查詢有何不一樣以及查詢結果的不一樣。對比查詢結果發現都是主鍵ID爲1的車輛:非視圖是163條關聯數據,而視圖狀況下是58條。再看一下查詢語句你會發現非視圖狀況的foreignField爲'FormItems.value.id'而視圖狀況下爲'1572493552001.id',根據外鍵來看,視圖明顯縮小了範圍,這裏就三張表而且只有車輛耗損表中有此字段,可是'FormItems.value.id'就不同了,車輛營收表中也表單項的值是這樣的結構。也就是說非視圖的關聯查詢查出了全部表中具備相似結構的關聯數據,而視圖狀況下在這裏僅查詢的是車輛耗損表中的關聯數據。雖然如今查詢車輛的耗損信息沒有問題,可是若是另一個表中也‘1572493552001’這個字段而且結構也是同樣的,那麼查詢仍然存在問題。因此穩妥的辦法應該是關聯查詢的時候首先肯定哪一個表以後纔是哪一個字段。orm
測試5、htm
db.getCollection('FormInstace').aggregate([ { $match: { "FormItems.key": { $ne: null } } }, { $addFields: { FormValueObj: { $arrayToObject: { $map: { input: "$FormItems", as: "field", in: [ "$$field.key", "$$field.value" ] } } } } }, { $replaceRoot: { newRoot: { $mergeObjects: [ "$FormValueObj", "$$ROOT" ] } } }, { $project: { FormItems:0, FormValueObj:0 } }, { $match: { "_id": { $in: ["1","2","3"] }, } }, { $lookup:{ from:"FormInstace", let: { tempMainRelationKey1: "$_id" }, pipeline:[ { $match: { FormId: "507048044944692000" } }, { $addFields: { FormValueObj: { $arrayToObject: { $map: { input: "$FormItems", as: "field", in: [ "$$field.key", "$$field.value" ] } } } } }, { $replaceRoot: { newRoot: { $mergeObjects: [ "$FormValueObj", "$$ROOT" ] } } }, { $project: { FormItems:0, FormValueObj:0 } }, { $match: { $expr: { $eq: [ "$1572493552001.id","$$tempMainRelationKey1" ] } } }, ], as:'RelationData' } } ]);
此次查詢在關聯的時候就肯定了FormId(指定車輛耗損表),以後再用外鍵等值查詢,所以這個查詢結果沒有問題。和前面筆記中:查詢車輛信息表中主鍵ID爲1的車輛的全部耗損記錄的結果相同都是58條……
好了就到這裏了,謝謝。