apache / incubator-hugegraph

A graph database that supports more than 100+ billion data, high performance and scalability (Include OLTP Engine & REST-API & Backends)
https://hugegraph.apache.org
Apache License 2.0
2.63k stars 517 forks source link

[Bug] 使用cypher api查询,提示Unsupported predicate: 'containing(XXXX)' #2572

Closed skysider closed 2 months ago

skysider commented 3 months ago

Bug Type (问题类型)

rest-api (结果不合预期)

Before submit

Environment (环境信息)

{"versions":{"version":"v1","core":"1.3.0","gremlin":"3.5.1","api":"0.71.0.0"}}

Expected & Actual behavior (期望与实际表现)

使用 /graphs/{graph_name}/cypher POST接口: data如下:

MATCH(n:Node)
WHERE n.name CONTAINS 'Template'
RETURN n

发送后响应如下:

{'requestId': '5542a039-1dd2-40ae-adff-2eaacdf4dae0', 'status': {'message': "org.apache.tinkerpop.gremlin.driver.exception.ResponseException: Unsupported predicate: 'containing(Template)'", 'code': 400, 'attributes': {}}, 'result': {'data': None, 'meta': {}}}

Vertex/Edge example (问题点 / 边数据举例)

No response

Schema [VertexLabel, EdgeLabel, IndexLabel] (元数据结构)

No response

dosubot[bot] commented 3 months ago

To resolve the issue of the unsupported predicate 'containing(Template)' when using the Cypher API to query your graph, you can use an alternative approach by converting the predicate to a supported one. Specifically, you can use the within or without predicates.

Here is an example of how you can handle the containing predicate by converting it to a supported predicate:

switch ((Contains) bp) {
    case within:
        return Condition.in(pkey.id(), valueList);
    case without:
        return Condition.nin(pkey.id(), valueList);
    default:
        throw newUnsupportedPredicate(has.getPredicate());
}

In this code, the containing predicate is not directly supported, but you can use within or without as alternatives to achieve similar functionality. If you need to check for containment within a list of values, you can use within. If you need to check for non-containment, you can use without.

Additionally, according to the hugegraph-server documentation, the containing predicate is explicitly listed as unsupported. Therefore, using the within or without predicates is a necessary workaround to achieve similar query functionality. The documentation also lists other unsupported predicates such as endingWith, startingWith, and notContaining, so be mindful of these limitations when constructing your queries [1][2][3].

To continue talking to Dosu, mention @dosu.

skysider commented 2 months ago

@dosu 未来有计划支持吗?gremlin或者cypher或者resetful api接口,支持类似contain或者regex的函数接口

dosubot[bot] commented 2 months ago

目前在 HugeGraph 的 Gremlin、Cypher 或 RESTful API 接口中,尚未找到明确的计划或时间表来支持 CONTAINS 或正则表达式(regex)函数接口。不过,您可以通过插件机制来扩展这些功能。

例如,您可以使用 org.apache.hugegraph.opencypher.CypherPlugin 插件来添加自定义谓词和函数,从而增强 Cypher 查询的能力,包括更高级的文本搜索操作 [1][2]

此外,您还可以实现自定义的分词器和注册自定义分词器来支持更高级的文本搜索功能,如正则表达式或全文搜索 [3][4]

如果您有进一步的需求或问题,建议您关注 HugeGraph 的更新和社区讨论,以获取最新的开发计划和功能支持。

To continue talking to Dosu, mention @dosu.

imbajin commented 2 months ago

@dosu 未来有计划支持吗?gremlin或者cypher或者resetful api接口,支持类似contain或者regex的函数接口

Hi, gremlin 原生可以支持 contains/regex 的操作的, 例如 g.V().hasLabel("person").has("like", Text.contains("doge")) 或者基于内存的 filter()

另外它也支持例如 startWith/endWith 等, 可以参考代码

dosubot[bot] commented 2 months ago

您好,Gremlin 原生确实支持 containsregex 操作,例如:

g.V().hasLabel("person").has("like", Text.contains("doge"))

或者基于内存的 filter()

g.V().filter{ it.get().value("name").contains("Template") }

此外,Gremlin 还支持 startWithendWith 等操作。您可以参考相关代码来实现这些功能。

To continue talking to Dosu, mention @dosu.

skysider commented 2 months ago

@imbajin @dosu 尝试了一下g.V().hasLabel("person").has("like", Text.contains("doge")) 这种不行,关键字必须是分词后的单词,不一定能命中,另外一种基于filter的可以:

g.V().filter{ it.get().value("name").contains("Template") }

最终有效的语句:

g.V().filter{ it.get().value("name").contains("Template") }

或者

g.V().filter(values("name").is(Text.contains("Template")))
imbajin commented 2 months ago

@imbajin @dosu 尝试了一下g.V().hasLabel("person").has("like", Text.contains("doge")) 这种不行,关键字必须是分词后的单词,不一定能命中,另外一种基于filter的可以:

g.V().filter{ it.get().value("name").contains("Template") }

最终有效的语句:

g.V().filter{ it.get().value("name").contains("Template") }

或者

g.V().filter(values("name").is(Text.contains("Template")))

Thanks for the feedback, u could refer #294 #779 #1619 to build full-context-search index & try to enhance/DIY it

Also need to know that the filter() step should work in a small data size

PS: @dosu why u don't refer the legacy/closed issues for user questions now? And better to show link directly