Запрос MongoDB для нескольких массивов объектов - PullRequest
1 голос
/ 10 июля 2020

Допустим, у меня есть mongoSchema user со следующим полем

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}]

Исходя из этой информации, я хочу отобразить только сообщение, которое соответствует следующему предпочтение.

Например, сообщение с Engli sh до Японский , Engli sh до Китайский ( из первого набора языков)

, а также отправляйте сообщения с корейский на японский , корейский на английский sh (из набора второго языка)

Моя схема сообщений имеет

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

Например,

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

Что я должен поместить в фигурные скобки, чтобы получить сообщения с помощью указанный языковой набор

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

Ответы [ 2 ]

2 голосов
/ 12 июля 2020

В вашем примере объект запроса должен выглядеть так

{
  $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] }]
})
1 голос
/ 12 июля 2020

Похоже, что достаточно использовать basi c boolean logi c:

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