JanusGraph索引入门及模糊查询

JanusGraph模糊查询与索引

1. 索引

JanusGraph 支持两种不同类型的索引来加快查询处理:图形索引中心顶点索引

图形索引使从由其属性标识的顶点或边列表开始遍历的全局检索操作在大型图形上高效
中心顶点索引可加快通过图形的实际遍历,尤其是在遍历具有许多入射边的顶点时

1.1 图形索引

图形索引又分为两种类型的图形索引: 复合索引混合索引

复合索引非常快速、高效,但仅限于对以前定义的特定属性键组合的相等查找
混合索引可用于索引键的任意组合上的查找,并且除了根据支持索引存储的相等性外,还支持多个条件谓词

复合索引不需要配置索引后端,混合索引依赖索引后端

特性 复合索引 混合索引
依赖后端 依赖存储后端(Cassandra, HBase, Berkeley DB) 依赖索引后端(ElasticSearch, solr, Lucene)
模糊查询,范围查询等 不支持 支持
速度 快速 比复合慢
灵活性 仅限于固定组合属性键 可以任意组合属性键
支持条件谓词 不支持 支持
索引唯一性约束 支持 不支持

Label Constraint 只针对特定label的顶点或边进行索引,可以在创建索引时添加indexOnly()方法来进行限制

name = mgmt.getPropertyKey('name')
olt = mgmt.getVertexLabel('olt')
mgmt.buildIndex('byNameAndLabel',Vertex.class).addKey(name).indexOnly(olt).buildCompositeIndex()
mgmt.commit()

Ordering 对查询结果进行排序

  • 复合索引不支持排序查询,其会查询到的所有的符合条件的数据放入内存中进行排序
  • 混合索引支持排序查询,但是查询的属性必须是混合索引中存在的,否则会将所有查询结果放入内存中进行排序

1.2 中心顶点索引

中心顶点索引是按顶点单独生成的局部索引结构。
中心顶点索引是用来解决图库中臭名昭著的超级节点问题(有很多条边的节点)

在大型图形中,顶点可以有数千个入射边。遍历这些顶点可能非常慢,因为必须检索事件边的很大一部分,然后在内存中筛选以匹配遍历的条件。中心顶点索引可以使用本地化的索引结构仅检索需要遍历的边来加快此类遍历速度。
graph.tx().rollback()  //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
time = mgmt.getPropertyKey('time')
battled = mgmt.getEdgeLabel('battled')
//构建中心顶点索引参数列表(边标签名,自定义索引名称,边方向,排序顺序,属性键)
mgmt.buildEdgeIndex(battled, 'battlesByTime', Direction.BOTH, Order.desc, time)
mgmt.commit()
//Wait for the index to become available
ManagementSystem.awaitRelationIndexStatus(graph, 'battlesByTime').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getRelationIndex(battled, "battlesByTime"), SchemaAction.REINDEX).get()
mgmt.commit()

1.3 索引的生命周期

(1)索引状态和转换

(2)状态

  • INSTALLED 索引安装在系统中,但尚未在群集中的所有实例中注册
  • REGISTERED 索引已注册为群集中的所有实例,但未(尚未)启用
  • ENABLED 索引已启用且正在使用中
  • DISABLED 索引已禁用且不再使用

(3)操作

可通过 以下操作对索引执行以下操作,以便通过 更改其状态:mgmt.updateIndex()

  • REGISTER_INDEX 使用图形群集中的所有实例注册索引。安装索引后,必须将其注册到所有图形实例
  • REINDEX 从图形重新生成索引
  • ENABLE_INDEX 启用索引,以便查询处理引擎可以使用索引。必须先注册索引,然后才能启用索引。
  • DISABLE_INDEX 禁用图形中的索引,以便不再使用它。
  • REMOVE_INDEX 从图形中删除索引(可选操作)。仅在复合索引上。

2. 模糊查询

图库支持模糊查询,但模糊查询需要遍历所有的顶点/边,所以需要混合索引的支持

如果模糊查询时没有索引支持,gremlin会给出警告

10:24:38 WARN org.janusgraph.graphdb.transaction.StandardJanusGraphTx - Query requires iterating over all vertices [(name textRegex .合肥.)]. For better performance, use indexes

2.1 全文搜索

​ 当该值被索引为文本时,字符串被标记成单词包,允许用户有效地查询包含一个或多个单词的所有匹配项。这通常称为全文搜索

默认情况下, 字符串作为文本索引, 也可以在定义时显示的定义(比标准的混合索引定义多了Mapping.TEXT.asParameter()):

mgmt = graph.openManagement()
summary = mgmt.makePropertyKey('booksummary').dataType(String.class).make()
mgmt.buildIndex('booksBySummary', Vertex.class).addKey(summary, Mapping.TEXT.asParameter()).buildMixedIndex("search")
mgmt.commit()

​ 当字符串作为文本编制索引时, JanusGraph默认标记拆分非字母数字的字符串, 并删除少于2个字符的任何标记(具体看索引后端默认配置)

当字符串属性作为文本编制索引时,索引后端在图形查询中仅支持全文搜索谓词。全文搜索不区分大小写。

  • textContains: 如果(至少)文本字符串中的一个单词与查询字符串匹配, 则为true
  • textContainsPrefix: 如果(至少)文本字符串中的一个单词以查询字符串开头, 则为true
  • textContainsRegex: 如果(至少)文本字符串中的一个单词与给定正则表达式匹配, 则为true
  • textContainFuzzy: 如果(至少)文本字符串中的一个单词与查询字符串类似(基于 Levenshtein 编辑距离), 则为true
g.V().has('booksummary', textContains('unicorns'))
g.V().has('booksummary', textContainsPrefix('uni'))
g.V().has('booksummary', textContainsRegex('.*corn.*'))
g.V().has('booksummary', textContainsFuzzy('unicorn'))

2.2 字符串搜索

​ 当该值作为字符串编制索引时,该字符串是索引"样",无需任何进一步分析或标记化。这便于查询查找确切的字符序列匹配。这通常称为字符串搜索

​ 要将字符串属性键索引为字符序列, 而无需进行任何分析或标记化, 请将映射指定为: Mapping.STRING

mgmt = graph.openManagement()
name = mgmt.makePropertyKey('bookname').dataType(String.class).make()
mgmt.buildIndex('booksBySummary', Vertex.class).addKey(name,Mapping.STRING.asParameter()).buildMixedIndex("search")
mgmt.commit()

当字符串属性被索引为字符串时,索引后端在图形查询中仅支持以下谓词。字符串搜索区分大小写。

  • eq: 如果字符串与查询字符串相同
  • neq: 如果字符串与查询字符串不同
  • textPrefix: 如果字符串以给定的查询字符串开头
  • textRegex: 如果字符串值与给定正则表达式完全匹配
  • textFuzzy: 如果字符串值与给定的查询字符串类似(基于 Levenshtein 编辑距离)
g.V().has('bookname', eq('unicorns'))
g.V().has('bookname', neq('unicorns'))
g.V().has('bookname', textPrefix('uni'))
g.V().has('bookname', textRegex('.*corn.*'))
g.V().has('bookname', textFuzzy('unicorn'))

2.3 字符串和全文搜索

​ 如果索引后端使用ElasticSearch, 则可以将属性索引为文本和字符串, 从而允许您使用所有的谓词进行精确和模糊匹配

mgmt = graph.openManagement()
summary = mgmt.makePropertyKey('booksummary').dataType(String.class).make()
mgmt.buildIndex('booksBySummary', Vertex.class).addKey(summary,Mapping.TEXTSTRING.asParameter()).buildMixedIndex("search")
mgmt.commit()

2.4 TinkerPop文本谓词

​ 也可以将 TinkerPop 文本谓词与 JanusGraph 一起使用,但这些谓词不使用索引,这意味着它们需要在内存中进行筛选,这可能非常耗费内存。

g.V().has('bookname', startingWith('uni'))
g.V().has('bookname', endingWith('corn'))
g.V().has('bookname', containing('nico'))

3. 总结

​ JanusGraph的索引支持已经相对比较完善,对于不同种类的索引需求分别用复合索引、混合索引及中心顶点索引来实现不同的功能。在具体场景实现中,需要谨慎考虑索引的构建,其重要性应与Schema结构一样且息息相关。

​ 索引中的混合索引需要配置索引后端,在索引后端的选择中应该考虑以ElasticSearch优先。ElasticSearch不仅支持多种多样的查询功能,如全文搜索、范围搜索、模糊查询和评分算法等,还支持Lucene查询语法,同时使用人数多,社区活跃。

Image placeholder
cross
未设置
  33人点赞

没有讨论,发表一下自己的看法吧

推荐文章
从头开始学JanusGraph 0.4

介绍JanusGraph支持三种数据库后端:ApacheCassandra, ApacheHBase,and OracleBerkeleyDBJavaEditionBerkeleyDB是非分布式的数据

vue引入swiper vue使用swiper vue脚手架使用swiper /引入js文件/引入css文件

vue引入swipervue使用swipervue脚手架使用swiper/引入js文件/引入css文件欢迎加入前端交流群来获取视频资料以及前端学习资料:749539640转载文章请注明出处! 如果只是

4.图片加载从模糊到清晰

很常见的一个效果虽然前端无法获知加载进度,但是可以通过效果来模拟通过先拉大预览的小图将图片模糊,然后再加载大图模拟效果效果预览:https://codepen.io/andy-js/pen/dyPZv

为什么我使用了索引,查询还是慢?

经常有同学问我,我的一个SQL语句使用了索引,为什么还是会进入到慢查询之中呢?今天我们就从这个问题开始来聊一聊索引和慢查询。另外插入一个题外话,个人认为团队要合理的使用ORM,可以参考 ORM的权衡和

Linux Shell 脚本快速入门

shell脚本是在一个文件中写入一起执行的命令集。对于使用像dos操作系统的DOS,windows操作系统的bat,linux操作系统的files的人来说,这几乎都是相同的概念。你只需要把一串命令写

Linux Shell 脚本快速入门

shell脚本是在一个文件中写入一起执行的命令集。对于使用像dos操作系统的DOS,windows操作系统的bat,linux操作系统的files的人来说,这几乎都是相同的概念。你只需要把一串命令写入

Java 程序员眼中的 Linux_1.0.Linux 介绍

Linux介绍 Linux这个名字 Linux的Wiki介绍:http://zh.wikipedia.org/zh/Linux Linux也称:GNU/Linux,而其中GNU的全称又是:Gnu’sN

[Java 程序员眼中的 Linux] Linux 下常用压缩文件的解压、压缩

Linux下常用压缩文件的解压、压缩 常用压缩包解压命令整理 Linux后缀为.tar.gz格式的文件-解压 命令:tarzxvfXXXXXX.tar.gz Linux后缀为.bz2格式的文件-解压

笨办法 学Linux 安装Linux

Linux学习起步 Windows,VirtualBox虚拟机(.ova格式的预配置映像) 学习Linux你需要什么 VitualBox,虚拟机播放器。 putty,终端模拟器。 预配置的Virtua

Linux/Unix 基础:什么是 Linux?

简单来讲,Linux是一个操作系统(OS)。我们都很熟悉其他操作系统,就像Microsoftwindows,AppleMacOS,iOS,Googleandroid,等等这些,linux就像它们一样,

Linux/Unix 基础:Linux 的历史

Linux的诞生 在1991年,来自芬兰Helsinki大学的学生LinusTorvalds认为市场上应该有一个比较统一的Unix版本,从此他就开始为这个项目奋斗。后来这个项目就成为了Linux操作系

别小瞧了 Linux,安卓、华为的自研系统,均源自 Linux!

众所周知,目前国内已有众多的国产系统,基本上均源自linux,以linux为基础进行二次开发。比如红旗linux、深度等等。但不知道为什么,一说起某系统是基于linux而来,很多网友就瞧不起,并且会觉

Go语言高级编程_4.4 gRPC入门

4.4gRPC入门 gRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。gRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。本节将

0104 gradle入门

背景gradle的官网是www.gradle.org,标题介绍是:acceleratedeveloperproductivity,翻译过来:提高开发者的生产率;简要介绍:从手机app到微服务,从小的创

知道创宇杨冀龙:变被动为主动,引入黑客视角护航IOT安全

提到无锡,除了太湖的美你还能想到些什么?我想到的是物联网,作为大家公认的“物联网之城”,无锡的物联网产业发展迅猛。根据无锡市委领导介绍,无锡是目前全国唯一的国家传感网创新示范区,从2009年开始,无锡

你公司到底需不需要引入实时计算引擎?| 推荐

大数据发展至今,数据呈指数倍的增长,对实效性的要求也越来越高,于是像上面这种需求也变得越来越多了。那这些场景对应着什么业务需求呢?我们来总结下,大概如下:初看这些需求,是不是感觉很难?那么我们接下来来

echarts怎么引入到vue中?

准备工作:首先我们初始化一个vue项目,执行vueinitwebpackechart。接着我们进入初始化的项目下,安装echarts,npminstallecharts-S //或 cnpminsta

js中如何引入css文件以及路径问题

js中如何引入css文件以及路径问题一、在js中引入css文件的方法:1、通过document.createElement方法创建link标签;2、通过setAttribute方法设置link标签的c

axios怎么引入到vue中?

Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。在vue项目之中使用axios是一个非常明智的选择,因为vue官方已经宣称不再维护vue-resource,并且推荐使

为何jsx文件必须引入react

为何jsx文件必须引入react本质上来说JSX是React.createElement(component,props,...children)方法的语法糖。所以我们如果使用了JSX,我们其实就是在

如何引入react组件库

如何引入react组件库1、通过npm安装antd推荐(Node.js教程)antd是基于AntDesign设计体系的ReactUI组件库,主要用于研发企业级中后台产品。npminstall-Dant

jsp怎么引入css样式?

JSP页面引入CSS样式有三种方法,且其优先级不同。具体如下:外部样式,内嵌样式,行内样式。优先级依次增高!下面给大家具体介绍一下:1、外部样式jsp可以在link标签中使用href属性引入css文件

引入css文件不起作用?

引入css文件不起作用?按F12查看开发者工具中显示,有common.css,但是页面上的样式却没有改变,代码如下: Vue介绍 ... 解决方法:加了rel属性后就好了,rel是关联的意

.vue文件怎么引入本地图片

.vue文件怎么引入本地图片.vue文件引入本地图片,需要先将本地图片复制到项目的src\assets目录中,否则不能使用。然后在template标签中,使用img标签引用图片即可。本地图片路径:在.

js如何引入css文件?

js如何引入css文件?1、使用document.write方式输出引入css的link标签在调用文件的顶部加入下例代码 document.write(''); (注:有时你引用的文件还可能需要引用其