2011-11-09 1 views
3

私は単純な問題だと思っていたことに対処するのに問題があります。基本的には、java.util.Map<String, String>が必要です.idがマップキーになり、someFieldが値になります。ektorpを使ってidからcouchdbの文字列propにjava.util.Mapを取得するには

私は本当にこれに執着しています。これは非常に驚きです。それはJSONはそうと、

public Map<String, String> getSomeFields() throws JsonParseException, JsonMappingException, IOException { 
    ViewQuery q = new ViewQuery().designDocId("_design/" + entity.getSimpleName()).viewName("someField"); 
    String result = StreamUtils.inputStreamAsString(db.queryForStream(q), false); 
    TypeReference<Map<String, String>> mapTypeRef = new TypeReference<Map<String,String>>() {}; 
    // mapper is a Jackson ObjectMapper 
    return mapper.readValue(result, mapTypeRef); 
} 

これはすでに本当に醜いですが、それはまた、実際には動作しません。そして、

@View(map="function(d) { if (d.someField) { emit(d.someField, null); } }", name = "someField") 

と次のJavaを使用します。私は別のビューを書いてみました結果としてqueryForStreamには、クエリの結果だけでなく、ランダムな他のものも含まれます。これにより、readValueコールがIOExceptionをスローするようになります。

私も、これらすべての値を含む単一のオブジェクトを生成するreduceを使用してみましたが、その結果は

答えて

3

私はこのような何かをするだろう:

ViewQuery query = ... 

Map<String, String> map = new HashMap<String, String>(); 
for (ViewResult.Row row : db.queryView(query)) { 
    map.put(row.getId(), row.getKey()); 
} 

return map; 
+0

これが最も簡単な解決策になりそうだ、感謝を! (これはそのままでは動作しません。AFAICTでは、結果セットを取得する前に '.queryView'呼び出し結果で' .getRows() 'を実行する必要があります) – Gijs

2

あなたが解析事前にする必要があります...ソファーが十分に低下させない下げる文句ということですしましたCouchDBからの出力は、そのメタデータのすべてをクエリで返すことを避ける方法がないためです。

まず、ビューで適切なデータ(オブジェクトIDとその値)を発行する必要があります。

@View(map="function(d) { if (d.someField) { emit(d.id, d.someField); } }", name = "someField")

応答の形式は、JSONオブジェクトのString =>オブジェクトです。私はこれに全回答をマッピングし、JSON配列のキー "行"を持つオブジェクトを選択することから始めます。この配列の各要素は、キー "id"、 "key"、 "value"を持つ別のJSONオブジェクトです。これらのオブジェクトのそれぞれを出力のキー値のペアにマップする必要があります。

public Map<String, String> getSomeFields() 
     throws JsonParseException, JsonMappingException, IOException { 

    ViewQuery q = 
     new ViewQuery().designDocId("_design/" + 
     entity.getSimpleName()).viewName("someField"); 

    String queryRresult = 
     StreamUtils.inputStreamAsString(db.queryForStream(q), false); 

    TypeReference<Map<String, Object>> mapTypeRef = 
     new TypeReference<Map<String,Object>>() {}; 

    TypeReference<List<Map<String,String>>> rowsTypeRef = 
     new TypeReference<List<Map<String,String>>>() {}; 

    // Map of the top level results which includes the couch meta and the 
    // rows. We have to use object, because Each value is of a different 
    // type (string, ints, json objects) 
    Map<String,Object> topResultMap = 
     mapper.readValue(queryRresult, mapTypeRef); 

    // Once we have the top level result, cast the value for key "rows" as 
    // String, and parse it as a rows type, which is a list of maps. 
    List<Map<String,String>> rows = 
     mapper.readValue((String) topResultMap.get("rows"), rowsTypeRef); 

    // Finally iterator over that list pulling out the id and the value in 
    // the key and value for the results 
    Map<String,String> results = new HashMap<String,String>(); 
    for (Map<String,String> row : rows) 
     results.put(row.get("id"), row.get("value")); 

    // And return them 
    return results; 
} 

最後に、CouchDBビューの一部を縮小していないことを確認する必要があります。そうした場合、 "reduce = false"をソファに渡す必要があります。

関連する問題