无法检索 JSON 值
Cannot retrieve JSON value
我有以下看法
{
"views" : {
"categories" : {
"map" : "function (doc) { emit(doc._id,{"title":doc.title,"parentnode":doc.parentnode});}"
}
}
}
即,对于每个文档,return 一个具有两个键的 JSON 对象:title
和 parentnode
及其各自的值。该视图在 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);}"
}
}
}
在云端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?
跟进:如何从视图的输出中删除重复项?
Cloudant 客户端似乎无法与 org.json.JSONObject
一起使用。我得到了第一个使用 com.google.gson.JsonObject
和 org.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"}]
回答后续问题:
您可以在视图中使用缩减函数(求和或计数)来消除重复项,但这也需要您将键更改为数据的唯一键。所以,如果 title 和 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
我有以下看法
{
"views" : {
"categories" : {
"map" : "function (doc) { emit(doc._id,{"title":doc.title,"parentnode":doc.parentnode});}"
}
}
}
即,对于每个文档,return 一个具有两个键的 JSON 对象:title
和 parentnode
及其各自的值。该视图在 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);}"
}
}
}
在云端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?
跟进:如何从视图的输出中删除重复项?
Cloudant 客户端似乎无法与 org.json.JSONObject
一起使用。我得到了第一个使用 com.google.gson.JsonObject
和 org.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"}]
回答后续问题:
您可以在视图中使用缩减函数(求和或计数)来消除重复项,但这也需要您将键更改为数据的唯一键。所以,如果 title 和 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