Select nested fields in mongo db

2020-02-14 04:16发布

I have a collection in mongodb where fields are nested under a language root:

{
    en: {
        title: "eng title",
        content: "eng content",
    },
    it: {
        title: "it title",
        content: "it content"
    }
    //common attributes for all languages
    images: {
        mainImage: "dataURL",
        thumbImage: "dataURL"
    }
}

I have a variable called 'currentLang'; I need to find a document by title selecting only the "currentLang" object and the common fields (images in this example); but for the "currentLang" object, I would like to have the output document not nested; for example, having currentLang = "en"

desired output:

{
    title: "eng title",
    content: "eng content",
    images: {
        mainImage: "dataURL",
        thumbImage: "dataURL"
    }
}

Is this possible?

标签: mongodb
2条回答
兄弟一词,经得起流年.
2楼-- · 2020-02-14 04:56

You need to aggregate as below:

  • Construct a find object to match only the records containing($exists) the language.
  • Construct a Projection object to project the fields.

Code:

var currentLang = "en";
var project = {};
project["title"] = "$"+currentLang+".title";
project["content"] = "$"+currentLang+".content";
project["images"] = 1;

var find = {};
find[currentLang] = {"$exists":true};

db.collection.aggregate([
{$match:find},
{$project:project}
])
查看更多
爷的心禁止访问
3楼-- · 2020-02-14 04:59

I'm not sure how you're querying, so I'll assume you're going directly through the mongo client. Assuming you have defined a variable

>currentLang = "en";

You can run an aggregation operation and using the $project operator, restructure the presentation of the document.

Here's an example that I've tested:

> db.test.aggregate({$project: 
        {_id: 0, 
         title: "$" + currentLang + ".title", 
         content: "$" + currentLang + ".content", 
         images: 1
        }
    }).pretty();
{
    "images" : {
        "mainImage" : "dataURL",
        "thumbImage" : "dataURL"
    },
    "title" : "eng title",
    "content" : "eng content"
}

If you want to combine this with an actual query, you can just include it as a $match operator, something like:

> db.test.aggregate(
    {$match: 
        {"en.title": "eng title"}
    }, 
    {$project: 
        {_id: 0, 
         title: "$" + currentLang + ".title", 
         content: "$" + currentLang + ".content", 
         images: 1
        }
    }).pretty();
查看更多
登录 后发表回答