添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

While using aggregation pipeline on collection having DBRef to other collection, using $lookup does not resolve to value due to $id field in the reference.

Imagine we have a collection called posts with the following structure.
" _id " : ObjectId ( " 5126bbf64aed4daf9e2ab771 " ), " title " : " Once in a Lifetime " , " content " : " Morbi quis tortor id nulla ultrices aliquet. " , " author " : { " $ref " : " users " , " $id " : ObjectId ( " 5126bc054aed4daf9e2ab772 " )

The DBRef in this example points to a document in the users collection that has ObjectId("5126bc054aed4daf9e2ab772") in its _id field.

To resolve, author field we need to use $lookup stage, which has syntax as given below but will not work, due to the presence of $ in the field name.

db.posts.aggregate([
        $lookup: {
            from: "users",
            localField: "author['$id']", // or author.$id
            foreignField: "_id",
            as: "author"

One of the workaround I found to resolve the DBRefs with $lookup operator, was with using $objectToArray, $arrayElemAt and $addFields operator.

Idea behind this is to somehow, extract the $id value in author field and then use $lookup operator to get the desired result.

db.posts.aggregate([
        $addFields: {
            "author": {
                $arrayElemAt: [{ $objectToArray: "author" }, 1]
        $addFields: {
            "author": "author.v"
        $lookup: {
            from: "users",
            localField: "author",
            foreignField: "_id",
            as: "author"
        $addFields: {
            "author": { $arrayElemAt: ["$author", 0] }
        "_id": ObjectId("5126bbf64aed4daf9e2ab771"),
        "title": "Once in a Lifetime",
        "content": "Morbi quis tortor id nulla ultrices aliquet.",
        "author": {
            "_id": ObjectId("5126bc054aed4daf9e2ab772"),
            "name": "Uta Charman",
            "avatar": "https://robohash.org/porroasperioreshic.png?size=50x50&set=set1",
            "aboutText": "Vivamus tortor."

Converts author object from DBref reference to array of key value pairs, and extracts key-value pair of $id in author field
author: { k: $id, v: ObjectId("5126bc054aed4daf9e2ab772") "_id": ObjectId("5126bc054aed4daf9e2ab772"), "name": "Uta Charman", "avatar": "https://robohash.org/porroasperioreshic.png?size=50x50&set=set1", "aboutText": "Vivamus tortor." author: { "_id": ObjectId("5126bc054aed4daf9e2ab772"), "name": "Uta Charman", "avatar": "https://robohash.org/porroasperioreshic.png?size=50x50&set=set1", "aboutText": "Vivamus tortor."

Very helpful article!

There is a missing $ from the snippet below. It took me hours to figure it out.
$addFields: {
"author": {
$arrayElemAt: [{ $objectToArray: "$author" }, 1]
$addFields: {
"author": "$author.v"
Full-stack developer. Strive to develop efficient backend solutions and design beautiful & UX friendly frontend. Enjoys the music of keyboard, avid podcast listener and a horror movie buff.

Built on Forem — the open source software that powers DEV and other inclusive communities.

Made with love and Ruby on Rails. DEV Community © 2016 - 2024.