我正在使用npm模块traverse来过滤来自mongodb / mongoose的数据。
我可能会得到这些数据:
[ { rating: 5,
title: { da: 'Web udvikling', en: 'Web Development' } },
{ rating: 5, title: { da: 'Node.js', en: 'Node.js' } } ]
'da'和'en'表示语言。我使用traverse来过滤当前语言之后的猫鼬数据,如下所示:
var filtered = filterLanguage(lang, results);
// filter json obj by language
var filterLanguage = function(language, obj) {
return traverse(obj).map(function (item) {
if (this.key === language) {
this.parent.update(item);
}
});
};
然后我在我的模板中显示:
res.render('index', {
skills: filtered.skills
});
最后我在玉石视图中显示它:
ul.list-group
each skill, i in skills
if i < 5
li.list-group-item.sidebar-list-item= skill.title
不幸的是它显示引号:
<ul>
<li>'Web Development'</li>
<li>'Node.js'</li>
</ul>
未过滤的数据(results.skill.title.da
)中没有这些引号。因此,遍历正在添加它们。我使用了'普通'json的模块,它运行得很好。
mongoose数据看似简单明了,但当然原型上有很多属性。如果我没有从结果集中省略'_id'(类型bson / objectid)属性,也会遍历停顿。
因此,遍历似乎有猫鼬数据的问题......为什么会这样?我该如何解决?
- 编辑 -
我找到了解决方案:
在过滤之前我这样做:
var json = JSON.parse(JSON.stringify(results));
var filtered = filterLanguage(lang, json);
这删除了引号,但我不确定它的作用。以某种方式将mongoose结果转换为JSON?我们将非常感谢您的解释。
答案 0 :(得分:0)
Mongoose文档中的字段是getter / setter,它们似乎混淆了traverse
或Jade / Pug。
我发现的最短的方法似乎解决了所有问题,这非常难看:
var filtered = filterLanguage(lang, results.map(r => JSON.parse(JSON.stringify(r))));
更精细的版本:
var filtered = filterLanguage(lang, results.map(r => {
let j = r.toJSON()
j._id = j._id.toString()
return j;
}));
答案 1 :(得分:0)
查看filterLanguage
的正文是什么有用或理解为什么它被调用两次会有所帮助,但就目前而言,我认为你根本不需要使用traverse
包
如下所示的功能应该可以解决这个问题,如果数据更像树状,并且不像示例中所示那样平坦,我甚至可以将其扩展为工作。
const reduceByLang = (data, lang) => {
// Look for a `lang` key in obj or
// if not found but still an object, recurse
const reduceByLangObj = (obj) => {
Object.keys(obj).forEach((key) => {
if (obj[key] === null) {
return;
}
if (obj[key][lang]) {
obj[key] = obj[key][lang]; // replace with desired lang
} else if (typeof obj[key] === 'object') {
reduceByLangObj(obj[key]); // recurse
}
});
return obj;
};
if (Array.isArray(data)) {
return data.map(reduceByLangObj);
} else {
return reduceByLangObj(data);
}
};
请参阅JS Bin中的示例。
此外,如果可能的话,如果您经常进行此类型的选择,我会考虑将数据保存在不同的结构中:
{ ratings: x, locales: { en: { title: 'Y' }, { da: { title: 'Z' } } } }
也许,这样您就可以在查询本身和/或控制器中轻松选择所选语言。
编辑:检查是否为空。