3

単純な問題だと思っていたものに対処するのに苦労しています。基本的に、java.util.Map<String, String>IDがマップキーになりsomeField、ドキュメントの値が最終的になる、が必要です。

私は本当にこれに固執しています、それは私を大いに驚かせます。別のビューを書いてみました:

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

次に、次のJavaを使用します。

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

これはすでに本当に醜いですが、実際には機能しません。queryForStream返されるJSONの結果には、クエリの結果だけでなく、他のランダムなものが含まれているようです。これにより、readValue呼び出しは。をスローしIOExceptionます。

また、これらすべての値を含む単一のオブジェクトを生成するためにを使用reduceしてみましたが、その結果、Couchはreduceが十分に減少しないと文句を言います...

4

2 に答える 2

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;
于 2011-11-11T16:03:39.920 に答える
2

クエリですべてのメタデータを返すことを回避する方法がないため、CouchDBからの出力を事前に解析する必要があります。

まず、ビューは正しいデータ(オブジェクトIDとその値)を出力する必要があります。

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

応答の形式は、JSONオブジェクトString=>Objectです。まず、応答全体をこれにマッピングしてから、JSON配列であるキー「rows」を持つオブジェクトを選択します。この配列の各要素は、キー「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部分がないことを確認する必要があります。その場合、「reduce=false」をカウチに渡す必要があります。

于 2011-11-09T16:33:26.503 に答える