Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 基于多个对象数组的MongoDB查询_Node.js_Mongodb_Mongoose_Mongodb Query_Mern - Fatal编程技术网

Node.js 基于多个对象数组的MongoDB查询

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

假设我有一个用户的mongoSchema,带有以下字段

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
只有这样您才能对其进行排序,我将添加一个简单的聚合,从用户开始显示它。