我想获得MongoDB集合中所有键的名称。
例如,从这个:
db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] } );
db.things.insert( { hello : [] } );
我想获得唯一的键:
type, egg, hello
我想获得MongoDB集合中所有键的名称。
例如,从这个:
db.things.insert( { type : ['dog', 'cat'] } );
db.things.insert( { egg : ['cat'] } );
db.things.insert( { type : [] } );
db.things.insert( { hello : [] } );
我想获得唯一的键:
type, egg, hello
当前回答
你可以用MapReduce来做:
mr = db.runCommand({
"mapreduce" : "my_collection",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "my_collection" + "_keys"
})
然后在结果集合上单独运行,以便找到所有的键:
db[mr.result].distinct("_id")
["foo", "bar", "baz", "_id", ...]
其他回答
我试着用nodejs写,最后想到了这个:
db.collection('collectionName').mapReduce(
function() {
for (var key in this) {
emit(key, null);
}
},
function(key, stuff) {
return null;
}, {
"out": "allFieldNames"
},
function(err, results) {
var fields = db.collection('allFieldNames').distinct('_id');
fields
.then(function(data) {
var finalData = {
"status": "success",
"fields": data
};
res.send(finalData);
delteCollection(db, 'allFieldNames');
})
.catch(function(err) {
res.send(err);
delteCollection(db, 'allFieldNames');
});
});
读取新创建的集合“allFieldNames”后,删除它。
db.collection("allFieldNames").remove({}, function (err,result) {
db.close();
return;
});
你可以用MapReduce来做:
mr = db.runCommand({
"mapreduce" : "my_collection",
"map" : function() {
for (var key in this) { emit(key, null); }
},
"reduce" : function(key, stuff) { return null; },
"out": "my_collection" + "_keys"
})
然后在结果集合上单独运行,以便找到所有的键:
db[mr.result].distinct("_id")
["foo", "bar", "baz", "_id", ...]
我很惊讶,这里没有人使用简单的javascript和Set逻辑来自动过滤重复的值,下面是mongo shellas的简单例子:
var allKeys = new Set()
db.collectionName.find().forEach( function (o) {for (key in o ) allKeys.add(key)})
for(let key of allKeys) print(key)
这将打印集合名称:collectionName中所有可能的惟一键。
以Kristina的回答为灵感,我创建了一个名为Variety的开源工具,它的功能就是:https://github.com/variety/variety
这对我来说很有效:
var arrayOfFieldNames = [];
var items = db.NAMECOLLECTION.find();
while(items.hasNext()) {
var item = items.next();
for(var index in item) {
arrayOfFieldNames[index] = index;
}
}
for (var index in arrayOfFieldNames) {
print(index);
}