$ lookup多个级别

时间:2018-08-01 13:59:52

标签: mongodb mongoose mongoose-populate

当前我有以下查询:

Post.find().populate([
    {
        path: 'page',
        populate: {
            path: 'url',
            populate: {
                path: 'i18n',
                match: {
                    locale: 'es_ES'
                }
            }
        }
    }
]);

结果,我得到:

{
    "title": "Title Post",
    "page": {
        "title": "Title Page",
        "url": [
            {
                "url": "/english",
                "i18n": null
            },
            {
                "url": "/spanish",
                "i18n": {
                    "name": "Spanish",
                    "iso": "es",
                    "locale": "es_ES",
                }
            }
        ]
    }
}

url在查询后被过滤:

let url = posts.page.url.filter(value => {
    return value.i18n;
});

我只想加载具有url条件的i18n.locale = es_ES关系,但是我不知道该怎么做。想要的结果:

{
    "title": "Title Post",
    "page": {
        "title": "Title Page",
        "url": [
            {
                "url": "/spanish",
                "i18n": {
                    "name": "Spanish",
                    "iso": "es",
                    "locale": "es_ES",
                }
            }
        ]
    }
}

我尝试过:

Post.find().populate([
    {
        path: 'page',
        populate: {
            path: 'url',
            match: {
                'i18n.locale': 'es_ES'
            }
        }
    }
]);

但这不是有效的过滤器。

型号:

module.exports = mongoose.model('i18n', new Schema({
    name: String,
    iso: String,
    locale: String
}));

module.exports = mongoose.model('page', new Schema({
    title: Object,
    url: [{
        type: Schema.Types.ObjectId,
        ref: 'url'
    }]
));

module.exports = mongoose.model('post', new Schema({
    title: Object,
    page: {
        type: Schema.Types.ObjectId,
        ref: 'page'
    }
}));

module.exports = mongoose.model('url', new Schema({
    url: String,
    i18n: {
        type: Schema.Types.ObjectId,
        ref: 'i18n'
    }
}));

我使用的是MongoDB服务器版本3.6.6和Mongoose 5.2.6。

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以在mongodb 3.6中尝试以下聚合

Post.aggregate([
  { "$lookup": {
    "from": Page.collection.name,
    "let": { "page": "$page" },
    "pipeline": [
       { "$match": { "$expr": { "$eq": [ "$_id", "$$page" ] } } },
       { "$lookup": {
         "from": Url.collection.name,
         "let": { "url": "$url" },
         "pipeline": [
           { "$match": { "$expr": { "$in": [ "$_id", "$$url" ] } } },
           { "$lookup": {
             "from": i18n.collection.name,
             "let": { "i18n": "$i18n" },
             "pipeline": [
               { "$match": { "$expr": { "$eq": [ "$_id", "$$i18n" ] } } }
             ],
             "as": "i18n"
           }},
           { "$addFields": { 
             "i18n": { "$arrayElemAt": [ "$i18n", 0 ] }
           }}
         ],
         "as": "url"
       }}
     ],
     "as": "page"
  }},
  { "$unwind": "$page" }
])