2017-04-11 89 views
0

我有以下视图无法检索JSON值

{ 
    "views" : { 
    "categories" : { 
     "map" : "function (doc) { emit(doc._id,{"title":doc.title,"parentnode":doc.parentnode});}" 
    } 
    } 
} 

即,对于每个文件,返回一个JSON对象,具有两个密钥:titleparentnode与它们各自的值。视图运行在cloudant UI

{ 
"id": "3bacce314363eb954f1922ff3cd2240c", 
"key": "3bacce314363eb954f1922ff3cd2240c", 
"value": { 
    "title": "poi", 
    "parentnode": "asd" 
}, 
"_id": "3bacce314363eb954f1922ff3cd2240c" 
} 

这是完美就好了。现在,我尝试在我的Java程序作为

List<JSONObject> vals = cloudant.getViewRequestBuilder("categoryDesign", "categories") 
.newRequest(com.cloudant.client.api.views.Key.Type.STRING, JSONObject.class) 
.includeDocs(true) 
.build() 
.getResponse() 
.getValues(); 

注意JSONObject在这种情况下org.json.JSONObject;阅读本。但是,为了这个,我得到

[{}] 

所以后来我改变了看法有点

{ 
     "views" : { 
     "categories" : { 
      "map" : "function (doc) { emit(doc._id,doc.title+":"+doc.parentnode);}" 
     } 
     } 
    } 

,并在cloudant UI我看到

{ 
"id": "9db1f03e8f4d239a6e18d4612b1a4275", 
"key": "9db1f03e8f4d239a6e18d4612b1a4275", 
"value": "poi:asd", 
"_id": "9db1f03e8f4d239a6e18d4612b1a4275" 
} 

,现在我做

List<String> vals = cloudant.getViewRequestBuilder("categoryDesign", "categories") 
.newRequest(com.cloudant.client.api.views.Key.Type.STRING, String.class) 
.includeDocs(true) 
.build() 
.getResponse() 
.getValues(); 

现在,输出是

["poi:asd"] 

我能做些什么来读取值为JSONObject s?

跟进:如何从视图的输出中删除重复项?

回答

1

Cloudant客户端似乎不能与org.json.JSONObject一起使用。我得到你的第一个例子与com.google.gson.JsonObjectorg.apache.wink.json4j.JSONObject一起工作。下面是Maven依赖:

com.google.gson.JsonObject:

<dependency> 
    <groupId>com.google.code.gson</groupId> 
    <artifactId>gson</artifactId> 
    <version>2.7</version> 
</dependency> 

org.apache.wink.json4j.JSONObject:

<dependency> 
    <groupId>org.apache.wink</groupId> 
    <artifactId>wink-json4j</artifactId> 
    <version>1.4</version> 
</dependency> 

输出System.out.println(vals.toString())

[{"parentnode":"asd","title":"poi"}] 

要回答后续问题:

您可以通过在视图中使用reduce函数(sum或count)来消除重复项,但这也需要您将密钥更改为数据的唯一密钥。所以,如果标题和parentnode的组合是你想成为你的唯一关键是什么,你的看法是这样的:

"categoriesNoDups": { 
    "reduce": "_sum", 
    "map": "function (doc) { emit([doc.title, doc.parentnode], 1); } }" 
} 

现在,当你打电话给你的视图(注意新视图命名为categoriesNoDups)你要添加?group=true像这样:

https://youraccount.cloudant.com/yourdb 
/_design/categoryDesign/ 
_view/categoriesNoDups?group=true 

的数据将类似于以下内容:

{ 
    "rows": [ 
    { 
     "key": [ 
     "poi", 
     "asd" 
     ], 
     "value": 2 
    } 
    ] 
} 

现在,而不是得到的值哟你想得到钥匙。要在Java中检索密钥,您应该这样做:

List<Key.ComplexKey> keys = cloudant.getViewRequestBuilder("categoryDesign", "categoriesNoDups") 
    .newRequest(Key.Type.COMPLEX, Number.class) 
    .group(true) 
    .build() 
    .getResponse() 
    .getKeys(); 
    for (Key.ComplexKey key : keys) { 
     JSONArray keyValues = new JSONArray(key.toJson()); 
     System.out.println("title = " + keyValues.getString(0)); 
     System.out.println("parentnode = " + keyValues.getString(1)); 
    } 

现在您又回到处理数组而不是JSON对象。另请注意:我使用Apache Wink JSON库将键转换为JSON对象(它们只是数组),然后访问这些对象的值。输出看起来类似于以下内容:

title = poi 
parentnode = asd 
+0

谢谢!那工作。关于后续的任何想法? – AbtPst

+0

查看最新答案 – markwatsonatx

+0

非常感谢!这样可行 – AbtPst