【问题标题】:$lookup multiple levels$lookup 多个级别
【发布时间】:2019-01-09 03:24:40
【问题描述】:

目前我有这个查询:

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;
});

我只想加载 urli18n.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。

谢谢!

【问题讨论】:

  • 你也可以分享数据吗?
  • 添加了模型。我认为不需要这些数据。使用 i18n 直接填充并在查询后过滤它可以工作。但是使用 'i18n.locale': 'es_ES' 过滤会被 mongoose 省略。
  • 发帖模型??
  • 问题是关于猫鼬过滤器的使用,而不是关于模式。无论如何添加了帖子模型。
  • 如果没有,你的查询应该可以工作,然后在这里使用聚合

标签: mongodb mongoose mongoose-populate


【解决方案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" }
])

【讨论】:

  • 非常感谢您的贡献,但对我来说太复杂了,无法理解。我是mongodb新手,申请前需要了解:)无论如何,谢谢。
  • 别担心它看起来很复杂,但你会在一段时间后得到它......如果你需要冗长的解释,那么你可以通过这个stackoverflow.com/questions/49953780/…
猜你喜欢
  • 2021-06-11
  • 2015-01-22
  • 1970-01-01
  • 2019-03-30
  • 2021-11-08
相关资源
最近更新 更多