无法检索JSON值

时间:2017-04-11 13:33:51

标签: java json view couchdb cloudant

我有以下观点

{
  "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 个答案:

答案 0 :(得分: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)来消除重复项,但这也需要您将密钥更改为数据的唯一键。因此,如果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