【问题标题】:URL-unsafe Secondary Index names in Riak do not workRiak 中的 URL 不安全的二级索引名称不起作用
【发布时间】:2013-05-02 10:04:35
【问题描述】:

我正在使用 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 客户端应该与此有什么关系。

谢谢!!

【问题讨论】:

    标签: riak


    【解决方案1】:

    今早查看,是的……HTTP API 和 URL 编码的索引名称和索引值存在问题。

    问题是这样的:标题名称和值不是 URL 解码并在您发布时按原样存储,但是当您发出 GET 请求时,URL 的分层部分(其中包含索引名称和值)解码。此外,+ 而不是 %20 也是一个问题。

    如果您使用 %20 并通过 URL 转义 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
    

    结果:

    {"keys":["my_key"]}

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

    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+not+url+safe%23%40%C2%A3%21
    指数+%40%24+价值
    [关键]

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

    不幸的是,如果您尝试在其他地方使用 HTTP,这肯定会出现问题。因为 java 中包含的 URLEncoder 类使用 +,所以使用使用 %20 的不同 URL 编码器(或执行 String.replaceAll())会有所帮助,但您仍然必须处理使用 HTTP 的 URL 转义查询。

    归结为,如果您使用 HTTP API,带有 2i 的非 US-ASCII(或特殊字符)会出现问题。

    更新:我认为这很容易解决,并有一个 PR:https://github.com/basho/riak_kv/pull/543 - 最后讨论了一个问题,因此可能需要额外的工作。我们目前将冻结 riak 1.4 的代码,因此可能要到下一个版本才能使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多