如何将JSON对象结构转换为点表示法?

时间:2015-10-08 02:25:05

标签: javascript mongodb

我有一个我正在存储的变量,它将决定从查询中排除哪些字段:

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中执行此操作?

3 个答案:

答案 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})