Mongodb 从mongoose中的类似嵌套字段列表中选择相同字段
我有一个模式Mongodb 从mongoose中的类似嵌套字段列表中选择相同字段,mongodb,mongoose,mongoose-schema,Mongodb,Mongoose,Mongoose Schema,我有一个模式 const placeSchema = new Schema({ description: { fr: String, en: String, }, comment: { fr: String, en: String, }, ... ... }); const Place= mongoose.model('Place', placeSchema); module.exports =
const placeSchema = new Schema({
description: {
fr: String,
en: String,
},
comment: {
fr: String,
en: String,
},
...
...
});
const Place= mongoose.model('Place', placeSchema);
module.exports = Place;
如果我只想获得我当前使用的“en”值
wait Place.find({},'-description.fr-comment.fr…)
如果相似字段的数量增加,查询的长度也会增加。有没有一种方法可以选择所有类似的字段,比如$field.fr?技术上是的,有一种方法。使用并执行一些结构操作 它看起来像这样:
db.collection.aggregate([
{
$match: {} //match your document.
},
{
$addFields: {
rootArr: {
$objectToArray: "$$ROOT"
}
}
},
{
$unwind: "$rootArr"
},
{
$match: {
"rootArr.v.en": {
$exists: true
}
}
},
{
$group: {
_id: "$_id",
data: {
$push: {
k: "$rootArr.k",
v: "$rootArr.v.en"
}
}
}
},
{
$replaceRoot: {
newRoot: {
$arrayToObject: "$data"
}
}
}
])
这是一个有点“黑客”的想法,你的模式需求有多严格?
您是否考虑过在以下结构下建造它
const placeSchema = new Schema({
data: [
{
lang: String,
description: String,
comment: String,
...
}
]
});
以下聚合将检查子字段的所有顶级字段
en
。如果是truthy(如果您严格使用语言属性的字符串值,则应该可以使用),则子字段将是{field:{en:fieldValue.en}}
,否则它将是{field:fieldValue}
db.collection.aggregate([
{
$replaceRoot: {
newRoot: {
$arrayToObject: {
$map: {
input: { $objectToArray: "$$ROOT" },
in: {
k: "$$this.k",
v: {
$cond: [
"$$this.v.en", // works for string values, otherwise you will have to check more explicitly
{
en: "$$this.v.en"
},
"$$this.v"
]
}
}
}
}
}
}
}
])
以上两个答案正是问题想要的。这可能是一种更“黑客”的做事方式 首先创建一个函数,生成查询字符串
'-description.fr-comment.fr…'
let select = '';
const selectLanguage = (fields, lang) => {
switch (true) {
case lang === 'fr':
fields.forEach(field => {
select= `${select} -${field}.en `;
});
break;
case lang === 'en':
fields.forEach(field => {
select = `${select} -${field}.fr `;
});
break;
default:
break;
}
return select;
}
这将生成一个字符串,如英语为'-fieldName1.fr-fieldName2.fr..
,法语为'-fieldName1.en..
。然后我们可以在上面的查询中使用这个语句
const select = selectLanguage(['description', 'comment', ..], 'en')
await Place.find({}, select) //await Place.find({}, ' -description.fr -comment.fr ..')
我将切换到这个模式,因为它看起来更好,对我来说更有效。但是,如果我希望所有数据的评级都相同,那么嵌套字段(比如:
impression:{备注:String,rating:Number}
)会有问题吗?最终,你会最清楚如何使用数据,你应该试着找到让生活更轻松的最佳结构。数组中的嵌套字段有时会很麻烦,但Mongo提供了许多工具来处理它们。例如,[arrayFilters][使更新这些阵列变得非常容易。