【问题标题】:Mongoose schema field names and types with subdocs带有子文档的猫鼬模式字段名称和类型
【发布时间】:2016-02-07 17:30:01
【问题描述】:

我正在从我的架构中构建一个字段名称及其类型的对象:

var ret = {};
ThisCollection.schema.eachPath(function(path) {
  ret[path] = ThisCollection.schema.path(path).instance;
});

这很好,除非架构中有嵌套数组。我似乎无法弄清楚如何访问子文档及其字段的类型。我试过了:

ThisCollection.schema.path("dot.notation").instance

在递归函数中构建更深路径的点符号名称。这似乎不起作用。

示例架构:

 var Person = new Schema({
    person_code: String, 
    person_name: String, 
    location_details:[{
        location_name: String,
        location_code: String
    }]
});

明确地说,我正在寻找我的返回对象以在结构上与我的架构相匹配,以便嵌套架构是我的返回对象中的嵌套对象,例如:

{
    person_code: String,
    person_name: String,
    location_details:{
        location_name: String,
        location_code: String
    }
}

【问题讨论】:

  • @JohnnyHK 为清楚起见更新了问题
  • 您已经忘记了location_details 是一个数组这一事实,这是您想要的吗?你最终想用这个做什么?这对我来说没有多大意义。如果您需要,为什么不直接保存原始架构定义对象?
  • @JohnnyHK 是的,我故意丢失了数组。稍后我需要另一个功能才能“读取”我声明的架构(字段名称及其声明的类型),并且我的架构有时是用户定义的。我对 Mongo/Mongoose/Node 还很陌生,所以我可能遗漏了很多小东西。您可能会使用原始模式定义对象进行某些操作,这就是我尝试使用 schema.paths 访问的内容
  • @JohnnyHK 你是在正确的道路上,我正在寻找的是ThisCollection.schema.tree,你想发布一个答案然后为赏金?

标签: node.js mongodb mongoose


【解决方案1】:

您可以通过

获取子文档的属性类型
[Collection].schema.paths.[sub-doc].schema.paths.[sub-doc-property].instance   // it will give dataytpe

你可以根据你有多少嵌套的子文档来嵌套它

您可以使用您的收藏

ThisCollection.schema.paths.location_details.schema.paths.location_name.instance   // String

_

/**
* @param {Object} coll       - Collection
* @param {string} props      - properties, eg. "abc", "abc.xyz", upto n number of nested dot notation
*/
function getType(coll, props) {
    return props.split('.').reduce(function (p, n, index, array) {
        if (index < array.length - 1) {
            return p.schema.paths[n];
        }
        return p.schema.paths[n].instance;
    }, coll);
}

var type = getType(ThisCollection, "location_details.location_name");
console.log(type); // String

【讨论】:

    【解决方案2】:

    最简单的解决方案可能是简单地保存用于创建架构的架构定义对象:

    var personSchemaDef = {
        person_code: String,
        person_name: String,
        location_details: [{
            location_name: String,
            location_code: String
        }]
    };
    var personSchema = new Schema(personSchemaDef);
    var Person = mongoose.model('person', personSchema, 'people');
    

    但您也可以从架构的tree 属性中获取架构的层次结构详细信息:

    console.log(Person.schema.tree)
    

    输出:

    { person_code: [Function: String],
      person_name: [Function: String],
      location_details:
       [ { location_code: [Function: String],
           location_name: [Function: String] } ],
      _id:
       { type: { [Function: ObjectId] schemaName: 'ObjectId' },
         auto: true },
      id:
       VirtualType {
         path: 'id',
         getters: [ [Function: idGetter] ],
         setters: [],
         options: {} },
      __v: [Function: Number] }
    

    【讨论】:

      【解决方案3】:

      这里的关键是从路径创建一个对象,特别是带有点符号字符串的路径。您可以使用以下方法设置给定属性和值的对象;

      var ret = {};
      var setObject = function(name, schema, context) {
          var parts = name.split("."), 
              p = parts.pop(),
              value = schema.path(p).instance;
          for(var i=0, j; context && (j=parts[i]); i++){
              context = (j in context ? context[j] : context[j]={});
          }        
          return context && p ? (context[p]=value) : undefined; // Object
      }
      
      ThisCollection.schema.eachPath(function(path) {         
          setObject(path, ThisCollection.schema, ret);        
      });
      

      【讨论】:

      • 这不能回答我的问题。 ThisCollection.schema.path(path).instance 似乎没有使用点符号路径。
      • 这看起来可行。我会测试一下并回复你。
      • 如果其中有一个是数组或对象,它仍然无法解决每个级别的诅咒。
      猜你喜欢
      • 2017-12-13
      • 1970-01-01
      • 1970-01-01
      • 2018-08-20
      • 2017-01-23
      • 2020-06-16
      • 2012-12-28
      • 1970-01-01
      • 2014-12-12
      相关资源
      最近更新 更多