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] }]
})
假设我有一个 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] }]
})