MongoDB list projection of subfield

僤鯓⒐⒋嵵緔 提交于 2019-12-08 11:37:22

问题


With SQL analogy, I need to SELECT root.subfield1.subfield2 FROM collection, that produces a list of subfield2 ... Using a Example: import this datapackage.json by

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

and work at terminal with mongo command:

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

the result is one array element (.count()=1) with subfields containing the names, not a list of names.


DUMPS

obtained:

{
    "_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"
        }]
    }
    }]
}

wanted:

"alpha2","English","alpha3-b", "alpha2", "English" ...


回答1:


I find the command!! it is not find() :-)

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

db.collection.distinct


(edit)

Ops, the "strictly correct" answer is a list (where repeat itens is possible) not a set (where no repeat occurs). See the case of db.lang_meta.distinct("resources.mediatype"), where the correct solution must return a list of four repeated items, not only one.

For list we can use map()... Well, suppose only one item, it would be ...

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

but must iterate over .resources and over .fields, so

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;
});

... that is near but not the ideal (elegant) solution.

Returning to the resources.mediatype example, that is a better illustration to the "repeat itens",

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;
});

That produces "text/csv", "text/csv", "text/csv", "text/csv" (!) but in a array-of-array structure... not a simple array.

Solution?

Lets do something with db.lang_meta.find({},{"resources.schema.fields.name":1}) ...



来源:https://stackoverflow.com/questions/32716677/mongodb-list-projection-of-subfield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!