Riak中URL不安全的辅助索引名称不起作用

时间:2013-05-02 10:04:35

标签: riak

我正在使用Riak 1.3.1并尝试创建二进制索引名Indexed field name @$@$@ @$ not url safe#@£!。我能够使用此索引成功保存密钥。

当我直接使用键值查询此键时,我得到了这个结果:

{"indexedFieldValue":"index @$ value","keyValue":"093741d5-940a-49a6-b742-be22c1773e87","indexes":{"Indexed field name @$@$@ @$ not url safe#@£!":"index @$ value"}}

现在,当我尝试使用URL /index/Indexed+field+name+%40%24%40%24%40+%40%24+not+url+safe%23%40£%21_bin/value使用此索引进行查询时,我没有收到任何响应: {"keys":[]}

  • 我做错了什么,或者
  • Riak不支持需要URL编码的索引名称吗?

注意:我使用Riak Java客户端编写数据(使用Java客户端通过二级索引查询时获得相同的结果),但我没有看到Java客户端应该如何处理这个问题。

谢谢!

1 个答案:

答案 0 :(得分:2)

今天上午调查,是的...... HTTP API和URL编码的索引名称和索引值存在问题。

问题是:标题名称和值 URL解码并在POST时按原样存储,但是当您发出GET请求时,URL的层次结构部分(包含索引名称和值) 已解码。此外,+代替%20也是一个问题。

如果您使用%20和网址转义GET,它实际上有效(请注意我将£替换为%A3):

curl -X POST -H 'x-riak-index-Indexed%20field%20name%20%40%24%40%24%40%20%40%24%20not%20url%20safe%23%40%C2%A3%21_bin: index%20%40%24%20value' -d 'Some Value' http://localhost:8098/buckets/test_bucket/keys/my_key

然后

curl localhost:8098/buckets/test_bucket/index/Indexed%2520field%2520name%2520%2540%2524%2540%2524%2540%2520%2540%2524%2520not%2520url%2520safe%2523%2540%25C2%25A3%2521_bin/index%2520%2540%2524%2520value

结果:

  

{ “键”:[ “my_key”]}

另一方面,

协议缓冲区不会遇到这些问题。如果您将Java客户端与协议缓冲区一起使用,则以下工作正常(请注意客户端自动对索引参数进行url-encode,就像键和桶一样):

IRiakClient client = RiakFactory.pbcClient();
Bucket b = client.fetchBucket("test_bucket").execute();

String s = "Indexed field name @$@$@ @$ not url safe#@£!";
String s2 = URLEncoder.encode(s, "UTF-8");
System.out.println(s2);
String v = "index @$ value";
String v2 = URLEncoder.encode(v, "UTF-8");
System.out.println(v2);

IRiakObject ro = RiakObjectBuilder.newBuilder("test_bucket", "key")
                  .addIndex(s2, v2)
                  .withValue("Some value")
                  .build();

b.store(ro).execute();

List<String> index = b.fetchIndex(BinIndex.named(s2))
                      .withValue(v2)
                      .execute();

System.out.println(index);

client.shutdown();

输出:

  

收录+字段+名称+%40%24%40%24%40 +%40%24 + +不URL +安全%23%40%C2%A3 21%
  指数+%40%24 +值
  [键]

事实上,协议缓冲区根本不需要你进行URL编码......它将通过UTF8字节发送,并乐意将它们用于索引名称和值。您可以从上面的示例中删除URL编码,并查看它是否有效。

不幸的是,如果您尝试在其他地方使用HTTP,这肯定会有问题。由于java中包含的URLEncoder类使用+,因此使用使用%20(或执行String.replaceAll())的其他网址编码器会有所帮助,但您仍需要使用HTTP查询处理URL转义。

如果您使用HTTP API,那么带有2i的非US-ASCII(或特殊字符)是有问题的。

更新:我认为这很容易修复并且有PR:https://github.com/basho/riak_kv/pull/543 - 最后讨论了一个问题,因此可能需要额外的工作。我们目前要对riak 1.4进行代码冻结,因此在下一个版本发布之前可能无法使用。