问题
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