MongoDB 查询多个对象数组

MongoDB query on multiple array of objects

假设我有一个 user 的 mongoSchema,其中包含以下字段

googleId: String,
name: String,
Language : [{}],

用户最初可以在其个人资料页面上指定一组语言集[最多 5 种]。

例如,用户可以如下设置 2 种语言:

语言:

[main: {name: English, code: ko}, secondary: [{name:Japanese, code: jp}, {name:Chinese, code: en}]], 

[main: {name: Korean, code: ko}, secondary: [{name:Japanese, code: jp}, {name:English, code: en}]

根据此信息,我只想渲染出符合以下偏好的 post。

例如 post 与 英语日语, 英语中文(来自第一语言集)

以及post与韩语日语,韩语英语(来自第二语言集)

我的 post 架构有

    postName: String
    original: {},
    target: {},

例如,

postName: 'Korean to Japanese Post'
original: {name: Korean, code: ko}
target: {name: Japanese, code jp}

我应该在大括号内放什么来获取具有指定语言集的 posts

const prefLang = req.user.Language
const post = await Post.find({ some query using prefLang to check over matching original and target })
res.send(translations)

听起来使用基本的布尔逻辑就足够了:

const prefLang = req.user.Language;

let conditions = [];

prefLang.forEach((langObj) => {
    let tragetLangs = langObj.secondary.map(lang => lang.code);
    conditions.push({
        $and: [
            {
                "original.code": langObj.main.code,
            },
            {
                "target.code": {$in: tragetLangs}
            }
        ]
    })
})

// you should check conditions !== empty array.
const post = await Post.find({$or: conditions})

您的示例的查询对象应如下所示

{
  $or: [
    {
      original: { name: "English", code: "en" },
      target: {
        $in: [{ name: "Japanese", code: "jp" }, { name: "Chinese", code: "cn" }]
      }
    },
    {
      original: { name: "Korean", code: "ko" },
      target: {
        $in: [{ name: "Japanese", code: "jp" }, { name: "English", code: "en" }]
      }
    }
  ]
}

所以你必须像这样从 prefLang 构造条件

const query = {
  $or: perfLang.map(lang => ({
    original: lang.main,
    target: { $in: lang.secondary }
  }))
}

const post = await Post.find(query)

提示:

如果语言对象有严格的模式,你可以这样定义它们

const LanguageSchema = new mongoose.Schema({
  name: String,
  code: String
}, {
  _id: false
})

const UserSchema = new mongoose.Schema({
  //...
  googleId: String,
  name: String,
  Language: [{ main: LanguageSchema, secondary: [LanguageSchema] }]
})