Node.js 基于多个对象数组的MongoDB查询
假设我有一个用户的mongoSchema,带有以下字段Node.js 基于多个对象数组的MongoDB查询,node.js,mongodb,mongoose,mongodb-query,mern,Node.js,Mongodb,Mongoose,Mongodb Query,Mern,假设我有一个用户的mongoSchema,带有以下字段 googleId: String, name: String, Language : [{}], 用户最初可以在其配置文件页面上指定语言设置数组[最多5个] 例如,用户可以设置以下两种语言: 语言: [main: {name: English, code: ko}, secondary: [{name:Japanese, code: jp}, {name:Chinese, code: en}]], [main: {name: Kore
googleId: String,
name: String,
Language : [{}],
用户最初可以在其配置文件页面上指定语言设置数组[最多5个]
例如,用户可以设置以下两种语言:
语言:
[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模式已被修改
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)
听起来使用基本布尔逻辑就足够了:
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})
听起来使用基本布尔逻辑就足够了:
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] }]
})
提示:
如果语言对象具有严格的模式,则可以这样定义它们
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] }]
})
对于您的示例,查询对象应该如下所示
{
$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] }]
})
提示:
如果语言对象具有严格的模式,则可以这样定义它们
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.)字段
语言
的实际模式是否在您的代码中定义?因为main:[Object]
表示对象数组,而[array]
表示数组数组数组。(2.)另外,在您的示例中,次要
应该有多个对象,对吗?当前,您有一个具有重复关键点的单个对象。(3.)您的帖子模式有original和target,但您没有提到user.original
和user.target
那么什么是req.user.original
和req.user.target
?它不是应该是用户语言吗。对不起,我打印了console.log。在模式中,它被定义为语言:[{}]2。是的,它应该是多个[{name:Japanese,code:jp},{name:Chinese,code:ch}]3)我应该只有const prefLanguage=req.user.Language。抱歉,我将编辑此信息(1)。字段语言的实际架构是否在代码中定义?因为main:[Object]
表示对象数组,而[array]
表示数组数组数组。(2.)另外,在您的示例中,次要
应该有多个对象,对吗?当前,您有一个具有重复关键点的单个对象。(3.)您的帖子模式有original和target,但您没有提到user.original
和user.target
那么什么是req.user.original
和req.user.target
?它不是应该是用户语言吗。对不起,我打印了console.log。在模式中,它被定义为语言:[{}]2。是的,它应该是多个[{name:Japanese,code:jp},{name:Chinese,code:ch}]3)我应该只有const prefLanguage=req.user.Language。抱歉,我会编辑此信息。这不是只列出与第一组匹配的帖子吗?我最多可以有5套语言。我想把它们都看一遍。然后我误解了数据结构,preflage
是我在注释中指定的那些对象的列表吗?是的,它是语言集对象的列表。抱歉,我没有说清楚。我编辑了我的答案以支持数组,逻辑仍然类似,但我们在构建的条件上执行了$或,因为可以有多个。您不能使用find添加自定义排序,即使您使用aggregate,您仍然必须手动添加一个占位符字段,如kr\u sort:1,jp_sort:2
只有这样你才能对它进行排序,我将添加一个简单的聚合,从用户开始显示它。这不是只列出与第一组匹配的帖子吗?我最多可以有5套语言。我想把它们都看一遍。然后我误解了数据结构,preflage
是我在注释中指定的那些对象的列表吗?是的,它是语言集对象的列表。抱歉,我没有说清楚。我编辑了我的答案以支持数组,逻辑仍然类似,但我们在构建的条件上执行了$或,因为可以有多个。您不能使用find添加自定义排序,即使您使用aggregate,您仍然必须手动添加一个占位符字段,如kr\u sort:1,jp_sort:2
只有这样您才能对其进行排序,我将添加一个简单的聚合,从用户开始显示它。