本章节主要为您提供使用GDB+ES的DSL编写指南

  1. 使用GDB+ES查询的基本形式
    • g.withSideEffect(‘GDB#fts’,enable)表示dsl要使用GDB+ES的全文检索
    • V()表示查询的为顶点的属性, E()表示查询为边的属性
    • HasStep()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()限定
    g.withSideEffect(‘GDB#fts’,‘enable’).V().has('${property-name}', 'GDB#* ${your-search-value}').limit(topN)
  2. GDB#match
    使用了ES中的match查询,为分词查询、模糊匹配、结果会根据相关度打分,搜索范围比较广,使得GDB具备了分词查询的能力,基本的查询形式为:
    • ${property-name}替换为您要搜索的字段
    • ${your-serach-value}替换为您要搜索的内容
    g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#match ${your-search-value}').limit(topN)

    例:查询desc字段中包含优秀青年的点

    g.withSideEffect('DB#fts','enable’).V().has('desc','GDB#match 优秀人才').limit(2)
    ==>[desc:[新世纪优秀人才支持计划]]
    ==>[desc:[全国优秀艺术人才]]
  3. 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:[新世纪优秀人才支持计划]]
  4. GDB#regexp

    使用了ES中的regexp正则查询,使得GDB具备了正则查询的能力,regexp正则查询功能非常强大

    g.withSideEffect('GDB#fts','enable').V().has('${property-name}', 'GDB#regexp ${your-search-value}').limit(20)

    例1: 查询localtion字段中以深圳开头的点

    g.withSideEffect('GDB#fts','enable').V().has('localtion', 'GDB#regexp 深圳.*').limit(topN)

    例2:查询localtion字段中以深圳结束的点

    g.withSideEffect('GDB#fts','enable').V().has('localtion', 'GDB#regexp .*深圳').limit(topN)

    例3:查询location字段包含深圳的点

    g.withSideEffect('GDB#fts','enable').V().has('localtion', 'GDB#regexp .*深圳.*').limit(topN)
    说明 在实际生产中,非常不建议您使用这种搜索的形式,因为这样需要全库扫描索引,非常耗时。如果您有这种包含查询的需求,首先建议您使用GDB#phrase查询,其查询的效果应该能满足您的大部分需求。总之,使用这样形式的包含查询,是在当您发现使用GDB#phrase与GDB#match都无法满足您的查询需求时才会使用这种形式的包含查询。
  5. GDB#string

    该查询使用了ES中的query_string,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#string为分词查询
  6. GDB#expression

    GDB#expression使用的也是query_sting查询形式如下:

    g.withSideEffect('GDB#fts','enable').V().has('*', 'GDB#expression ${your-search-expression}').limit(topN)
    • 其与GDB#string的区别是没有指定查询字段,用*代替
    • 请您将${your-serach-expression}替换为具体的查询表达式。

    例1: 在不知道具体字段的情况下,查询字段中包含深圳的点,这种查询效果通GDB#match类似,区别是不需要指定字段。

    g.withSideEffect('GDB#fts','enable').V().has('*', 'GDB#expression 深圳').limit(topN)

    例2:查询name是张三,location包含深圳的点

    g.withSideEffect('GDB#fts','enable').V().
    has('*', 'GDB#expression (predicates.name.value.keyword:张三)AND
    (predicates.location.value:深圳)').limit(topN)
    说明
    1. GDB中property的字段,在ES中的存储模型是不一样的,比如,name在ES中存储为predicates.name.value的形式
    2. 加上.keyword为等值查询。不加为分词查询,效果同GDB#match
  7. GDB#nokey

    GDB#nokey的查询效果和GDB#phrase类似,区别是GDB#nokey不需要指定搜索主建

    g.withSideEffect('GDB#fts', "enable").V().has('*', 'GDB#nokey ${your-search-value}').limit(topN)
  8. 使用建议
    • GDB#match相比GDB#match查询范围广,通常GDB#match搜索结果的前几名就是GDB#phrase的搜索结果,即GDB#match的模糊匹配能力是要大于GDB#phrase。注重查询的广度使用GDB#match,注重查询的精度使用GDB#pharse
    • 如果你有contain这种查询需求,建议优先使用GDB#phrase,其精度应该能满足您绝大部分的查询需求,如果您对搜索结果不满意,你可以使用GDB#regexp正则表达式查询,但是这种查询的耗时要比GDB#phrase