首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rexster + Bulbs: Unicode节点属性-已创建但未找到节点

Rexster + Bulbs: Unicode节点属性-已创建但未找到节点
EN

Stack Overflow用户
提问于 2014-04-14 18:36:02
回答 1查看 206关注 0票数 1

我正在使用bulbsrexster,并尝试存储具有unicode属性的节点(参见下面的示例)。显然,在图中创建节点可以正常工作,因为我可以在rexster (Rexster Dog House)附带的web界面中看到节点,但检索相同的节点却不起作用--我得到的只有None

当我创建和查找属性中包含非unicode特定字母的节点时,一切都按预期进行。例如,在以下示例中,具有name = u'University of Cambridge'的节点将如预期的那样是可检索的。

Rexster版本:

代码语言:javascript
复制
[INFO] Application - Rexster version [2.4.0]

示例代码:

代码语言:javascript
复制
# -*- coding: utf-8 -*-


from bulbs.rexster import Graph
from bulbs.model import Node
from bulbs.property import String
from bulbs.config import DEBUG
import bulbs

class University(Node):
    element_type = 'university'
    name = String(nullable=False, indexed=True)


g = Graph()
g.add_proxy('university', University)
g.config.set_logger(DEBUG)

name = u'Université de Montréal'

g.university.create(name=name)

print g.university.index.lookup(name=name)

print bulbs.__version__

在命令行上提供以下输出:

POST url: http://localhost:8182/graphs/emptygraph/tp/gremlin

POST body: {"params": {"keys": null, "index_name": "university", "data": {"element_type": "university", "name": "Universit\u00e9 de Montr\u00e9al"}}, "script": "def createIndexedVertex = {\n vertex = g.addVertex()\n index = g.idx(index_name)\n for (entry in data.entrySet()) {\n if (entry.value == null) continue;\n vertex.setProperty(entry.key,entry.value)\n if (keys == null || keys.contains(entry.key))\n\tindex.put(entry.key,String.valueOf(entry.value),vertex)\n }\n return vertex\n }\n def transaction = { final Closure closure ->\n try {\n results = closure();\n g.commit();\n return results; \n } catch (e) {\n g.rollback();\n throw e;\n }\n }\n return transaction(createIndexedVertex);"} GET url: http://localhost:8182/graphs/emptygraph/indices/university?value=Universit%C3%A9+de+Montr%C3%A9al&key=name

GET body: None None 0.3

EN

回答 1

Stack Overflow用户

发布于 2014-04-17 03:35:17

好了,我终于搞清楚了。

由于TinkerGraph使用HashMap作为其索引,因此您可以通过使用Gremlin返回地图的内容来查看索引中存储的内容。

下面是使用上面的灯泡g.university.create(name=name)方法存储在TinkerGraph索引中的内容……

代码语言:javascript
复制
$ curl http://localhost:8182/graphs/emptygraph/tp/gremlin?script="g.idx(\"university\").index"
代码语言:javascript
复制
{"results":[{"name":{"Université de Montréal":[{"name":"Université de Montréal","element_type":"university","_id":"0","_type":"vertex"}]},"element_type":{"university":[{"name":"Université de Montréal","element_type":"university","_id":"0","_type":"vertex"}]}}],"success":true,"version":"2.5.0-SNAPSHOT","queryTime":3.732632}

所有这些看起来都很好--编码看起来是正确的。

为了创建和索引类似上面的顶点,Bulbs通过一个带有JSON内容类型的HTTP POST请求使用了一个定制的Gremlin脚本。

问题是..。

Rexster的索引查找REST端点使用URL查询参数,而Bulbs将URL参数编码为UTF-8字节字符串。

为了了解Rexster如何处理编码为UTF-8字节字符串的URL查询参数,我通过一个URL查询参数执行了一个Gremlin脚本,该参数只返回编码的字符串...

代码语言:javascript
复制
$ curl http://localhost:8182/graphs/emptygraph/tp/gremlin?script="'Universit%C3%A9%20de%20Montr%C3%A9al'"
代码语言:javascript
复制
{"results":["Université de Montréal"],"success":true,"version":"2.5.0-SNAPSHOT","queryTime":16.59432}

太棒了!那是不对的。如您所见,该文本已损坏。

具有讽刺意味的是,我们让Gremlin返回gremlins,这是Rexster在索引查找中使用的键值,正如我们所看到的,这并不是TinkerGraph的HashMap索引中存储的值。

事情是这样的.

下面是未加引号的字节字符串在灯泡中的样子:

代码语言:javascript
复制
>>> name
u'Universit\xe9 de Montr\xe9al'

>>> bulbs.utils.to_bytes(name)
'Universit\xc3\xa9 de Montr\xc3\xa9al'

'\xc3\xa9'是unicode字符u'\xe9' (也可以指定为u'\u00e9')的UTF8编码。

UTF-8使用2字节对字符进行编码,Jersey/Grizzly 1.x (Rexster的应用服务器)有一个错误,它不能正确处理像UTF-8这样的2字节字符编码。

请参阅http://markmail.org/message/w6ipdpkpmyghdx2p

看起来这个问题在Jersey/Grizzly 2.0中已经解决了,但是将Rexster从Jersey/Grizzly 1.x切换到Jersey/Grizzly 2.x是一个巨大的考验。

去年TinkerPop决定改用Netty,因此对于今年夏天发布的Gremlin 3,TinkerPop正在向基于Netty而不是Grizzly的Gremlin服务器过渡。

在此之前,这里有几个变通方法...

由于Grizzly不能处理像UTF-8这样的2字节编码,客户端库需要将URL参数编码为1字节latin1编码(AKA 8859-1),这是Grizzly的默认编码。

下面是编码为latin1字节字符串的相同值...

代码语言:javascript
复制
 $ curl http://localhost:8182/graphs/emptygraph/tp/gremlin?script="'Universit%E9%20de%20Montr%E9al'"
代码语言:javascript
复制
{"results":["Université de Montréal"],"success":true,"version":"2.5.0-SNAPSHOT","queryTime":17.765313}

正如您所看到的,在这种情况下使用latin1编码是可行的。

但是,出于一般目的,客户端库最好通过HTTP POST请求对JSON内容类型使用定制的Gremlin脚本,这样就可以完全避免URL param编码问题--这就是Bulbs将要做的事情,我将在今天晚些时候将Bulbs更新推送到GitHub。

更新:事实证明,即使我们不能改变Grizzly的默认编码类型,我们也可以在Content-Type请求头部中指定UTF8作为字符集,Grizzly将使用它。Bulbs 0.3.29已更新,在其请求标头中包含UTF-8字符集,并且所有测试都通过。更新已经被推送到GitHub和PyPi。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23057915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档