本文主要为您提供使用图数据库GDB+ES(Elasticsearch,搜索引擎)的DSL编写指南。
使用建议
GDB#match与GDB#phrase相比较,GDB#match查询范围广,一般情况下,GDB#match搜索结果的前几名即GDB#phrase的搜索结果。所以,GDB#match的模糊匹配能力大于GDB#phrase。
说明GDB#match:注重查询的广度。
GDB#phrase:注重查询的精度。
如果您有
contain
查询需求,建议您先使用GDB#phrase(精度应该能满足您绝大部分的查询需求),如果您对搜索结果不满意,您可以使用GDB#regexp正则表达式进行查询(耗时长)。
基本查询形式
g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#* ${your-search-value}').limit(topN)
g.withSideEffect('GDB#fts','enable')
表示DSL需要使用GDB+ES的全文检索。V()
表示查询的为顶点的属性。如果是E()
,表示查询为边的属性。has()
为GDB+ES的必要步骤。说明value以
'GDB#*'
开头,其中请将*替换为match、phrase
等。property-name
:请替换为您需要搜索的字段。your-search-value
:请替换为您需要搜索内容。其中,'GDB#*'
与${your-search-value}
之间必须有一个空格。
limit(topN)
:可以控制返回的条数,默认按照打分结果排序返回10条。即使是部分走ES查询,limit()
所限定的返回数也是经由ES查询的返回条数。因此,您的查询需求如果是先通过GDB+ES
的全文检索功能检索出特定的点,再对该点执行其他操作,需要适当调大limit()
。可以加上
hasLabel()
限定。
GDB#match
使用了ES中的match查询,为分词查询、模糊匹配、结果会根据相关度打分,搜索范围比较广,使得GDB具备了分词查询的能力,基本的查询形式为:
g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#match ${your-search-value}').limit(topN)
示例:查询desc字段中包含优秀人才的点
g.withSideEffect('GDB#fts','enable').V().has('desc','GDB#match 优秀人才').limit(2)
==>[desc:[新世纪优秀人才支持计划]]
==>[desc:[全国优秀艺术人才]]
GDB#phrase
使用了ES中的match_phrase
查询,也会进行分词查询,搜索范围比较小,搜索结果更加精准,类似GDB中的TextP.containing()
。
g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#phrase ${your-search-value}').limit(topN)
示例:查询desc字段中包含优秀人才的点
g.withSideEffect('GDB#fts','enable').V().has('desc','GDB#phrase 优秀人才').limit(2)
==>[desc:[新世纪优秀人才支持计划]]
GDB#regexp
在实际生产中,不建议您使用这种搜索形式。因为该搜索形式需要全库扫描索引,非常耗时。如果您有这种包含查询的需求,建议您使用GDB#phrase查询,其查询的效果应该能满足您的大部分需求。当您发现使用GDB#phrase与GDB#match都无法满足您的查询需求时使用该搜索形式的包含查询。
使用了ES中的regexp
正则查询,使得GDB具备了正则查询的能力,regexp正则查询功能非常强大。
g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#regexp ${your-search-value}').limit(20)
示例1: 查询location字段中以深圳开头的点
g.withSideEffect('GDB#fts','enable').V().has('location', 'GDB#regexp 深圳.*').limit(topN)
示例2:查询location字段中以深圳结束的点
g.withSideEffect('GDB#fts','enable').V().has('location', 'GDB#regexp .*深圳').limit(topN)
示例3:查询location字段包含深圳的点
g.withSideEffect('GDB#fts','enable').V().has('location', 'GDB#regexp .*深圳.*').limit(topN)
GDB#string
GDB#string为分词查询。
该查询使用了ES中的query_string
,支持AND OR NOT
等操作,详细信息请参见query_string链接。
g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#string ${your-search-value}').limit(topN)
示例:查询location
字段是深圳或者武汉的点
g.withSideEffect('GDB#fts','enable').V().has('location', 'GDB#string 深圳 OR 武汉').limit(topN)
GDB#expression
GDB中
property
的字段,在ES中的存储模型是不一样的,例如,name
在ES中存储为predicates.name.value
的形式。加上
.keyword
为等值查询;不加为分词查询,效果同GDB#match。
GDB#expression
使用的也是query_string
,查询形式如下:
g.withSideEffect('GDB#fts','enable').V().has('*', 'GDB#expression ${your-search-expression}').limit(topN)
其与
GDB#string
的区别是没有指定查询字段,用*代替。${your-serach-expression}
:请替换为具体的查询表达式。
GDB#nokey
GDB#nokey的查询效果和GDB#phrase类似,区别是GDB#nokey不需要指定搜索主键。
g.withSideEffect('GDB#fts', "enable").V().has('*', 'GDB#nokey ${your-search-value}').limit(topN)