无法检索 JSON 值

Cannot retrieve JSON value

我有以下看法

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

即,对于每个文档,return 一个具有两个键的 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();

请注意,在这种情况下 JSONObjectorg.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"]

我该怎么做才能将值读取为 JSONObjects?

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

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"}]

回答后续问题:

您可以在视图中使用缩减函数(求和或计数)来消除重复项,但这也需要您将键更改为数据的唯一键。所以,如果 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