我有一个我正在存储的变量,它将决定从查询中排除哪些字段:
excludeFields = {
Contact: {
Address: 0,
Phone: 0
}
}
我需要将其转换为可与Mongo的findOne
一起使用的点符号,例如:
things.findOne({}, {fields: {'Contact.Address': 0, 'Contact.Phone': 0}})
仅传递excludeFields
不起作用并导致错误,“投影值应为1,0,true或false之一”
things.findOne({}, {fields: excludeFields})
我是否必须编写自己的函数来从分层结构转换为平点符号?或者是否有一些机制可以在我不知道的JavaScript中执行此操作?
答案 0 :(得分:12)
这应该足够灵活,以满足大多数需求:
function dotNotate(obj,target,prefix) {
target = target || {},
prefix = prefix || "";
Object.keys(obj).forEach(function(key) {
if ( typeof(obj[key]) === "object" ) {
dotNotate(obj[key],target,prefix + key + ".");
} else {
return target[prefix + key] = obj[key];
}
});
return target;
}
运行excludesFields
变量,如下所示:
dotNotate(excludeFields);
它返回当前结构:
{ "Contact.Address" : 0, "Contact.Phone" : 0 }
所以你甚至可以这样做,内联:
things.findOne({}, {fields: dotNotate(excludeFields) })
或提供投影:
var projection = { "fields": {} };
dotNotate(excludeFields,projection.fields);
things.findOne({}, projection);
除非你需要像$push
这样的运算符,否则在所有深度都能很好地工作,甚至可以使用数组。
答案 1 :(得分:2)
我使用的函数与接受的答案非常相似
function convertJsonToDot(obj, parent = [], keyValue = {}) {
for (let key in obj) {
let keyPath = [...parent, key];
if (obj[key]!== null && typeof obj[key] === 'object') {
Object.assign(keyValue, convertJsonToDot(obj[key], keyPath, keyValue));
} else {
keyValue[keyPath.join('.')] = obj[key];
}
}
return keyValue;
}
在这里,我做了一个额外的检查' obj [key]!== null'因为不幸 null也属于' object'。
我实际上想将此评论添加到已接受的答案中,但由于声誉不足而无法做到。
答案 2 :(得分:1)
var fields = {};
for (var k in excludeFields) {
for (var p in excludeFields[k]) {
fields[k + '.' + p] = excludeFields[k][p];
}
}
然后:
things.findOne({}, {fields: fields})