MongoDB查詢實現 DBRef field的lookup

在Aggregation Pipeline Stages中,有一個$lookup函數,具體的用法如下

{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

而如果localField是 DBRef里面的$id,那么則不能lookup

   $lookup:
     {
       from: "tableA",
       localField: "tableA.$id",
       foreignField: "_id",
       as:"tableA"
     }
}

會返回如下錯誤

assert: command failed:
{ "ok" : 0, "errmsg" : "FieldPath field names may not start with '$'.", "code" : 16410 }

原因是管道函數中限制了fieldName不能以$開始,所以此處會報錯。

When change notification is first stage in aggregation any data manipulation that's done in that pipeline may need to project or check/use the value of "o.$__" field ($set, $unset, etc).

解決辦法:在lookup前加入下面管道代碼生成一個去掉$的field

{$addFields:{"newfoo":
     {$arrayToObject:{$map:{
          input:{$objectToArray:"$foo"}, 
          in:{
             k:{$cond:[ 
                     {$eq:[{"$substrCP":["$$this.k",0,1]},{$literal:"$"}]},
                     {$substrCP:["$$this.k",1,{$strLenCP:"$$this.k"}]},
                     "$$this.k"
             ]},
             v:"$$this.v"
           }
         }}}
}}

此處的newfoo為新增的field的別名,foo為DBRef的field,其它代碼為固定寫法,也就是可以復制此處代碼修改兩個地方,效果如下
before

{
    "foo":{
        "$ref":"foo",
        "$id":"123"
    }
}

after

{
    "foo":{
        "$ref":"foo",
        "$id":"123"
    },
    "newfoo":{
        "ref":"foo",
        "id":"123"
    }
}

那么我們就可以開心的使用lookup了。


參考官方還在OPEN的defectSERVER-14466,也許以后可以用$開頭作為fieldName使用,但是暫時的代替方法為上述方法.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容