MongoDB列表的子域投影

时间:2015-09-22 12:18:53

标签: mongodb projection

使用SQL类比,我需要SELECT root.subfield1.subfield2 FROM collection,它产生 subfield2的列表 ... 使用示例:通过

导入此datapackage.json

mongoimport -d lang_db -c lang_meta datapackage.json --jsonArray

使用mongo命令在终端上工作:

db.lang_meta.find({},{"resources.schema.fields.name":2})

结果是一个数组元素(.count() = 1),其子字段包含名称,而不是名称列表。

转储

获得:

{
    "_id": ObjectId("56011be94564569fc920eda4"),
    "resources": [{
    "schema": {
        "fields": [{
            "name": "alpha2"
        }, {
            "name": "English"
        }]
    }
    }, {
    "schema": {
        "fields": [{
            "name": "alpha3-b"
        }, {
            "name": "alpha2"
        }, {
            "name": "English"
        }]
    }
    }, {
    "schema": {
        "fields": [{
            "name": "alpha3-b"
        }, {
            "name": "alpha3-t"
        }, {
            "name": "alpha2"
        }, {
            "name": "English"
        }, {
            "name": "French"
        }]
    }
    }, {
    "schema": {
        "fields": [{
            "name": "lang"
        }, {
            "name": "langType"
        }, {
            "name": "territory"
        }, {
            "name": "revGenDate"
        }, {
            "name": "defs"
        }, {
            "name": "dftLang"
        }, {
            "name": "file"
        }]
    }
    }]
}

想:

  

" alpha2","英语"," alpha3-b"," alpha2","英语" ...

1 个答案:

答案 0 :(得分:0)

我找到命令!!它不是find(): - )

db.lang_meta.distinct("resources.schema.fields.name")

db.collection.distinct

(编辑)

行动,"严格正确"答案是列表(其中可以重复itens)而不是 set (不发生重复)。请参阅db.lang_meta.distinct("resources.mediatype")的情况,其中正确的解决方案必须返回四个重复项目的列表,而不仅仅是一个。

对于 list ,我们可以使用map() ......好吧,假设只有一个项目,那就是......

db.lang_meta.find().map(function(c) { 
  return c.resources[0].schema.fields[0].name; 
});

但必须遍历.resources并超过.fields,所以

db.lang_meta.find().map(function(c) {
    var ret = [];
    for (var i=0; i<c.resources.length; i++) 
        for (var j=0; j<c.resources[i].schema.fields.length; j++) 
             ret.push( c.resources[i].schema.fields[j].name );
   return ret;
});

......接近但不是理想(优雅)的解决方案。

回到resources.mediatype示例,这是更好的说明&#34;重复itens&#34;,

db.lang_meta.find().map(function(c) {
    var ret = [];
    for (var i=0; i<c.resources.length; i++) 
             ret.push( c.resources[i].mediatype );
   return ret;
});

产生"text/csv", "text/csv", "text/csv", "text/csv"(!) 但是在数组数组结构中......不是一个简单的数组。

解?

让我们用db.lang_meta.find({},{"resources.schema.fields.name":1}) ...

做点什么