我是MongoDB的新手,我有一个像这样的mongodb文件
{
"_id": 1,
"title": "abc123",
"author": {
"last": "zzz",
"first": "aaa",
"address": {
"street": "stvalue",
"city": "NewYork"
}
}
}
我正在使用MongoDB Java客户端并尝试将上述文档转换为
{
"_id": 1,
"title": "abc123",
"author_last": "zzz",
"author_first": "aaa",
"author_address_street": "stvalue",
"author_address_city": "New York"
}
使用MongoDB Java客户端是否可以使用MongoDB查询而不用Java修改结果。
更新
由于无法在MongoQuery中转换为所需的格式,因此我必须改变主意并添加一些Java代码以获得所需的格式。
答案 0 :(得分:2)
使用哪个“客户端”或“驱动程序库”并不是真正的问题,唯一的方法是通过.aggregate()
和$project
来“改变字段”作为回应。这是你最实际的方式:
db.collection.aggregate([
{ "$project": {
"title": 1,
"author_last": "$author.last",
"author_first": "$author.first",
"author_address_street": "$author.address.street",
"author_address_city": "$author.address.city"
}}
])
很容易翻译成任何语言,但会向您展示基本原则。
Very Java(esque)然后语法变为(在基本驱动程序中):
BasicDBObject project = new BasicDBObject("$project",
new BasicDBObject( "title", 1 )
.append( "author_last", "$author.last" )
.append( "author_first", "$author.first" )
.append( "author_address_street", "$author.address.street" ),
.append( "author_address_city", "$author.address.city" )
);
collection.aggregate(project);
如果您不能以这种方式指定密钥,那么服务器上唯一真正的选项是mapReduce。与上述方法大致相同,在客户端响应中执行此操作可能更好:
db.collection.mapReduce(
function() {
var item = {};
var id = this._id;
delete this._id;
var obj = this;
Object.keys(obj).forEach(function(key) {
if ( typeof(obj[key]) == "object" ) {
Object.keys(obj[key]).forEach(function(subKey) {
if ( typeof(obj[key][subkey] == "object" ) {
Object.keys(obj[key][subKey]).forEach(function(subSub) {
item[key + "_" + subKey + "_" + subSub] = obj[key][subKey][subSub];
});
} else {
item[key + "_" + subKey] = obj[key][subKey];
}
});
} else {
item[key] = obj[key];
}
});
emit( id, item );
},
function() {}, // no reduction required
{ "out": { "inline": 1 } }
)
我认为这是有道理的,但我只是输入它可能会出现语法问题,但这个想法应该是相关的。根据您的实际数据,您可能还需要更复杂的东西。
重点是,您需要JavaScript执行来“遍历”服务器上的文档才能使用此方法。
否则,只需在代码中执行相同的操作,因为无论如何都在迭代游标。
答案 1 :(得分:0)
这是一个Java实现,它将所有子对象转换为HashMap
private List<Map<String,String>> mapReduce(AggregationOutput output){
List<Map<String,String>> out = new ArrayList<Map<String, String>>();
for (DBObject result : output.results()) {
Map<String,String> map = ConvertDBObjectToMap(result, "");
out.add(map);
}
return out;
}
private Map<String,String> ConvertDBObjectToMap(DBObject result, String parent)
{
String prefix = parent == "" ? "" : parent + "_";
Map<String,String> out = new HashMap<String, String>();
String[] keys = result.keySet().toArray(new String[result.keySet().size()]);
for(String key : keys)
{
Object obj = result.get(key);
if(obj instanceof BasicDBObject)
{
out.putAll(ConvertDBObjectToMap((BasicDBObject) obj, prefix + key));
}
else if(obj instanceof String)
{
out.put(prefix + key,(String)obj);
}
else if(obj instanceof Date){
out.put(prefix + key,obj.toString());
}
else{
out.put(prefix + key,obj.toString());
}
}
return out;
}