学习Gremlin语言

深入学习1:https://blog.youkuaiyun.com/linlin1989117/article/details/82558475

V()E()id()label()properties()valueMap()values()

深入学习2:https://blog.youkuaiyun.com/linlin1989117/article/details/82658777

out()in()both()outE()inE()bothE()outV()inV()bothV()otherV()

深入学习3:https://blog.youkuaiyun.com/linlin1989117/article/details/82589895

hasLabel(labels…​)、hasId(ids…​)、has(key, value)、has(label, key, value)、has(key, predicate)、hasKey(keys…​)、hasValue(values…​)、has(key)、hasNot(key)

深入学习4:https://blog.youkuaiyun.com/u010260089/article/details/82594300

count()range()limit()tail()skip()

深入学习5:https://blog.youkuaiyun.com/linlin1989117/article/details/82625906

path()simplePath()cyclicPath()

深入学习6:https://blog.youkuaiyun.com/javeme/article/details/82760106

repeat()times()until()emit()loops()

深入学习7:https://blog.youkuaiyun.com/u010260089/article/details/82666260

order()by()

深入学习8:https://blog.youkuaiyun.com/javeme/article/details/82769457

group()groupCount()dedup()by()

深入学习9:https://blog.youkuaiyun.com/linlin1989117/article/details/82692587

where()filter()

深入学习10:https://blog.youkuaiyun.com/u010260089/article/details/82769959

is()and()or()not()

深入学习11:https://blog.youkuaiyun.com/u010260089/article/details/82787808

sum()max()min()mean()

深入学习12:https://blog.youkuaiyun.com/linlin1989117/article/details/82849477

math()

深入学习13:https://blog.youkuaiyun.com/javeme/article/details/88417208

as()+select()as()+where()as()+match()as()+dedup()

深入学习14:https://blog.youkuaiyun.com/linlin1989117/article/details/82703743

choose()branch()

深入学习15:https://blog.youkuaiyun.com/u010260089/article/details/82837664

coalesce()optional()union()

深入学习16:https://blog.youkuaiyun.com/javeme/article/details/88576363

aggregate()store()unfold()fold()

深入学习17:https://blog.youkuaiyun.com/linlin1989117/article/details/82855931

match()

深入学习18:https://blog.youkuaiyun.com/u010260089/article/details/82900950

sample()coin()constant()inject()

深入学习19:https://blog.youkuaiyun.com/javeme/article/details/89038027

sack()

深入学习20:https://blog.youkuaiyun.com/javeme/article/details/89182912

barrier()

深入学习21:https://blog.youkuaiyun.com/linlin1989117/article/details/82859866

local()count()max()mean()min()sum()order()tail()limit()range()sample()skip()limit()dedup()

深入学习22:https://blog.youkuaiyun.com/u010260089/article/details/82969173

hasNext()next()tryNext()toList()toSet()toBulkSet()fill()iterate()

深入学习23:https://blog.youkuaiyun.com/u010260089/article/details/82970917

mapflatMap()

深入学习24:https://blog.youkuaiyun.com/javeme/article/details/89184241

sideEffect()

深入学习25:https://blog.youkuaiyun.com/linlin1989117/article/details/82859884

profile()explain()

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

深入学习1:

    

g.V()    // 查询图中所有的顶点,注意:g 代表的是整个图(graph),一切查询都是以图开始
g.V('4:Gremlin', '3:TinkerPop') //根据id查询顶点

g.E()    //查询图中所有的边
g.E('S3:TinkerPop>4>>S4:Gremlin')    //根据id查询边

g.V().id()    // 查询所有顶点的id,边类似

g.V().label()    //查询所有顶点的label(标签,类型),边类似

g.V().properties()    //查询所有顶点的属性,边类似
g.V('2:lop').properties().key()    // properties()可以和 key()、value()搭配使用,以获取属性的名称或值。

g.V().properties('lang')    // 查询所有顶点的“lang”属性,如果无“lang”属性的顶点将跳过

g.V().valueMap()    // 查询所有顶点的属性,边类似
//valueMap()与 properties()不同的地方是:它们返回的结构不一样,后者将所有的属性扁平化到一个大列表里面,一个元素代表一个属性;前者保持一个顶点或一条边的属性作为一组,每一组由若干属性的键值对组成。

g.V().values()    //查询所有顶点的属性值,效果等同于:g.V().properties().value()
g.V().values('lang') // 查询所有顶点的“lang”属性,效果等同于:g.V().properties('lang').value()

深入学习2:

g.V().out()    //先查询图中所有的顶点,然后访问顶点的OUT方向邻接点,注意:out()的基准必须是顶点
g.V('3:TinkerPop').out() //id是'3:TinkerPop'的OUT方向邻接点
g.V('3:TinkerPop').out('define') //且限制仅“define”类型的边相连的顶点

g.V('3:TinkerPop').in()  //访问某个顶点的IN方向邻接点
g.V('3:TinkerPop').in('implements') //且限制了关联边的类型

g.V('3:TinkerPop').both()  //访问某个顶点的双向邻接点
g.V('3:TinkerPop').both('implements', 'define')  //且限制了关联边的类型

g.V('3:TinkerPop').outE()  //访问顶点的OUT方向邻接边
g.V('3:TinkerPop').outE('define')  //且限制了关联边的类型

g.V('3:TinkerPop').inE()  //访问某个顶点的IN方向邻接边
g.V('3:TinkerPop').inE('implements')  //且限制了关联边的类型

g.V('3:TinkerPop').bothE()  //访问某个顶点的双向邻接边
g.V('3:TinkerPop').bothE('define', 'implements')  //且限制了关联边的类型

g.V('3:TinkerPop').inE().outV()  //一般情况下,inE().outV()等价于in()
g.V('3:TinkerPop').outE().outV()  //顶点本身,条数按边的数量显示

g.V('3:TinkerPop').outE().inV()  //访问某个顶点的OUT邻接边,取边的入顶点。一般情况下,outE().inV()等价于out()
g.V('3:TinkerPop').inE().inV() //顶点本身,条数按边的数量显示

g.V('3:TinkerPop').outE().bothV() //获取边的双向顶点

g.V('3:TinkerPop').outE().otherV()//获取边的伙伴顶点

//顶点出发 顶点:out(),in(),both() 边:inE(),outE(),bothE()
g.V('2:TinkerPop').out()   //某定点出度的邻顶点
g.V('2:TinkerPop').outE()  //某顶点出度的邻边
g.V('2:TinkerPop').in()    //某顶点入度的邻顶点
g.V('2:TinkerPop').inE()   //某顶点入度的邻边
g.V('2:TinkerPop').both()  //某顶点入度和出度的邻顶点
g.V('2:TinkerPop').bothE() //某顶点入度和出度的邻边
g.V('2:TinkerPop').bothE('define', 'implements') //限制了关联边的类型,inE(),out()等等都可以
//边出发 只有顶点:outV(),inV(),bothV(),otherV()
g.V('2:TinkerPop').inE().outV()   //一般情况下,等价于in()
g.V('2:TinkerPop').outE().outV()  //顶点本身,条数按边的数量显示
g.V('2:TinkerPop').outE().inV()   //一般情况下,等价于out()
g.V('2:TinkerPop').inE().inV()    //顶点本身,条数按边的数量显示
g.V('2:TinkerPop').outE().bothV() //获取边的双向顶点  :本身,以及相邻的顶点
g.V('2:TinkerPop').outE().otherV()//获取边的伙伴顶点  :本身以外的顶点,相当于in(),out()

深入学习3:

// 对‘person’的‘addr’属性建立secondary索引,可以对Text类型property按值进行查询
graph.schema().indexLabel('personByCity').onV('person').by('addr').secondary().ifNotExist().create()
// 对‘person’的‘age’属性建立range索引,可以对Number类型property进行范围查询
graph.schema().indexLabel('personByAge').onV('person').by('age').range().ifNotExist().create()

//hasId(),hasLabel(),has(),hasValue(),hasNot()

g.V().hasLabel('person')  //查询label为"person"的顶点
g.V().hasLabel('person', 'software')  //查询label为"person"或者"software"的顶点

g.V().hasId('zhoney')  //查询id为"zhoney"的顶点
g.V().hasId('zhoney', '3:HugeGraph')  //查询id为“zhoney”或者“3:HugeGraph”的顶点

g.V().has('addr', 'Beijing')  //查询“addr”属性值为“Beijing”的顶点
g.V().has('person', 'addr', 'Beijing')  //查询label为“person”且“addr”属性值为“Beijing”的顶点
g.V().has('age', gt(20))  //查询 年龄>20 的顶点
g.V().has('age') //查询包含属性“age”的顶点,等价于has(key),但0.8.0版本的studio上测试,索引和未索引的字段都查询,结果未通过,报错:Not support query: Query for VERTEX offset=0, limit=9223372036854775807, order by {} where id in [] and [PROPERTIES containskey 3]  目前未找到原因

g.V().hasValue('Beijing') //查询包含属性值“Beijing”的顶点

g.V().hasNot('age') //查询没有属性“age”的顶点

深入学习4:

g.V().count()  //查询图中所有顶点的个数
g.V().hasLabel('person').count() //查询图中类型为“人person”的顶点数
g.V().hasLabel('person').outE('created').count() //查询图中所有的 “人创建created” 的边数
g.V().properties().count() //查询图中所有顶点的属性数

//限定查询返回的元素的范围,上下界表示元素的偏移量,左闭右开。下界以“0”作为第一个元素,上界为“-1”时表示取到最后的元素。
g.V().hasLabel('person').range(0, -1)  //不加限制地查询所有类型为“人person”的顶点
g.V().hasLabel('person').range(2, 5)  //查询类型为“人person”的顶点中的第2个到第5个
g.V().hasLabel('person').range(5, -1) //查询类型为“人person”的顶点中的第5个到最后一个

g.V().limit(2) //查询前两个顶点
g.E().limit(3) //查询前三条边

g.V().tail(2) //查询后两个顶点

g.V().hasLabel('person').skip(5) //0.8.0版本不支持

深入学习5:

// “HugeGraph”顶点到与其有直接关联的顶点的路径(仅包含顶点)
g.V().hasLabel('software').has('name','HugeGraph').both().path() 
//“HugeGraph”顶点到与其有直接关联的顶点的路径(包含顶点和边)
g.V().hasLabel('software').has('name','HugeGraph').bothE().otherV().path() 
//用“name”属性代表person和software顶点
g.V().hasLabel('software').has('name','HugeGraph').bothE().otherV().path().by('name').by('weight') 
//返回所有路径,包含有环路径和无环路径
g.V().hasLabel('software').has('name','HugeGraph').both().both().path() 

// “HugeGraph”顶点到与其有两层关系的顶点的不含环路的路径(只包含顶点)
g.V().hasLabel('software').has('name','HugeGraph').both().both().simplePath().path()

// “HugeGraph”顶点到与其有两层关系的顶点的包含环路的路径(只包含顶点)
g.V().hasLabel('software').has('name','HugeGraph').both().both().cyclicPath().path()

深入学习6:

//可以out(),both(),但没有in()
g.V('okram').repeat(out()).times(1) //访问某个顶点的OUT邻接点(1次)
g.V('okram').repeat(both()).times(2) //访问某个顶点的2度双向邻接点: 访问第1个顶点的所有邻接点(第1层),再访问第1层结果顶点的邻接点(第2层)

//这里用到了path()来获取经过的路径,path的讲解请参考上一期。
//until()与 times()是互斥的,两个语句无法同时存在于同一个循环中。
//until()放在repeat()之前或之后的顺序是会影响逻辑的,放前面表示先判断再执行,放后面表示先执行后判断。
g.V('okram').repeat(out()).until(has('name', 'Gremlin')).path() //查询顶点'okram'到顶点'Gremlin'之间的路径,环的终止条件是遇到名称是'Gremlin'的顶点

//注意:emit()放在repeat()之前或之后的顺序是会影响结果的,放前面表示先收集再执行,放后面表示先执行后收集。
//emit()与times()搭配使用时,是“或”的关系而不是“与”的关系,满足两者间任意一个即可。
g.V('okram').repeat(out()).emit().path()  //查询顶点'okram'的所有OUT可达点的路径
g.V('okram').repeat(out()).emit(hasLabel('person')).path()  //查询顶点'okram'的所有OUT可达点的路径,且必须满足是'person'类型的点
g.V('okram').repeat(out()).times(2).emit(hasLabel('person')).path() //查询顶点'okram'的2度OUT可达点的路径,此外还收集'person'类型的顶点

g.V('okram').repeat(out()).until(loops().is(3)).path() //查询顶点'okram'的3度OUT可达点路径
g.V('okram').repeat(out()).until(has('name', 'Gremlin').and().loops().is(2)).path() //查询顶点'okram'到顶点'Gremlin'之间的路径,且之间只相差2跳的距离,其中的and()是指两个条件都满足

// 查找从一个节点出发,到
// 叶子节点结束的所有路径
// 这些路径的集合为一颗子树(子图)
g.V('okram').repeat(out()).until(outE().count().is(0)).path()

// 已知两个顶点'okram'和'javeme',
// 通过任意关系来找到这两点之间的路径
// 且限制了最大深度为3
// 若存在那么第一条结果即是最短路径
g.V('okram').repeat(bothE().otherV().simplePath()).until(hasId('javeme').and().loops().is(lte(3))).hasId('javeme').path()

深入学习7:

g.V().values('name').order() //以默认(升序)排序输出所有顶点的"name"属性值
g.V().values('name').order().by(incr) //以升序输出所有顶点的"name"属性值
g.V().values('name').order().by(decr) //以降序输出所有顶点的"name"属性值
g.V().values('name').order().by(shuffle) //以随机序输出所有顶点的"name"属性值
g.V().hasLabel('person').order().by('age') //将"person"类型的顶点按照"age"升序(默认)排列输出
g.V().hasLabel('person').order().by('age').values('age')//将"person"类型的顶点按照"age"升序(默认)排列,并获取"age"属性
g.V().hasLabel('person').order().by('age', incr).values('age')//将"person"类型的顶点按照"age"升序排列,并获取"age"属性
g.V().hasLabel('person').order().by('age', decr).values('age')//将"person"类型的顶点按照"age"降序排列输出,并获取"age"属性
g.V().hasLabel('person').order().by('age', shuffle).values('age')//将"person"类型的顶点按照"age"随机序排列输出,并获取"age"属性

深入学习8:

g.V().hasLabel('person').group() //不指定任何维度进行分组
g.V().both().hasLabel('person').group() //不指定任何维度进行分组,重复的元素将会被分为一组
g.V().hasLabel('person').group().by('age')// 根据年龄进行分组
g.V().hasLabel('person').group().by('age').by(count())//根据年龄进行分组,并统计各个年龄的人数
g.V().group().by(label).by(count()) //根据顶点类别进行分组,并统计各个类别的数量

g.V().hasLabel('person').groupCount()//不指定任何维度进行分组计数
g.V().both().hasLabel('person').groupCount()//不指定任何维度进行分组计数,重复的元素将会被分为一组
g.V().hasLabel('person').groupCount().by('age')//根据年龄进行分组计数

g.V().both().hasLabel('person').dedup() //对一组含有重复顶点的数据进行去重
g.V().hasLabel('person').values('age').dedup() //查看所有人当中有哪几种年龄,通过dedup去除掉重复的年龄
g.V().hasLabel('person').dedup().by('age') //从各个年龄的人中选出一个代表

 

 

<think>首先,用户的问题是关于Gremlin图数据库查询语言的简介。我需要根据系统指令和用户需求来构建回答。 系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用:我有几个引用,需要适当引用它们。 用户的问题:"请问GREMLIN 图数据库 查询语言 简介",意思是请求Gremlin图数据库查询语言的简介。 引用内容: - [^1]: 提到Gremlin注重表达能力和灵活性。 - [^2]: Gremlin属于函数式编程语言,通过链式组合遍历操作符形成路径式表达式。 - [^3]: 图结构由点和边组成,Gremlin中称之为Vertex。 - [^4]: 图数据库查询语言没有统一标准,GQL正在制定中。 - [^5]: 基于Gremlin语言图数据库查询的优化,涉及标签结构。 我需要基于这些引用构建回答,因为用户说“上述引用仅供参考”,但它们是相关信息。用户意图是了解Gremlin简介。 回答结构: 1. **简介部分**:简要介绍Gremlin是什么,它在图数据库中的作用。 2. **核心特性**:解释Gremlin的核心特性,如函数式编程、链式表达式。 3. **基本元素**:描述图结构中的点和边在Gremlin中的表示。 4. **与其他语言的比较**:提及与其他图查询语言如Cypher、SPARQL的区别。 5. **示例**:提供一个简单的查询示例来展示Gremlin的用法。 6. **引用标识**:在相关部分末尾添加引用标识。 7. **相关问题**:最后生成相关问题。 使用中文回答。 生成相关问题:在回答结束时,添加一个“相关问题”部分。 确保LaTeX正确:用户的问题中没有数学表达式,但如果有,我会使用$...$或$$...$$。在这个上下文中,可能不需要数学表达式,除非涉及计算。 现在,构建回答大纲: - **开头**:直接回答用户问题,介绍Gremlin。 - **主体**: - 解释Gremlin的核心概念。 - 描述其函数式编程特性。 - 讨论图结构(Vertex和Edge)。 - 比较其他语言(基于引用)。 - **结尾**:总结或提供示例。 - **相关问题**:列出3-5个相关问题。 引用标识: - 在引用具体信息时添加[^n],如[^1], [^2]等。 相关问题想法: 1. Gremlin的基本语法是什么? 2. 如何优化Gremlin查询? 3. Gremlin在实际应用中的案例? 4. Gremlin与其他图查询语言的区别? 基于引用: - 引用[^2]提到查询示例:"从Hercules出发,遍历到他的父亲,再到他父亲的父亲,最后返回祖父的名字",我可以使用这个作为示例。 完整回答结构: 1. Gremlin简介:定义和目的。 2. 核心特性:函数式编程、链式表达式。 3. 图结构:点和边。 4. 查询示例。 5. 与其他语言的比较。 6. 相关问题。</think>### Gremlin图数据库查询语言简介 Gremlin是一种专为图数据库设计的查询语言,属于Apache TinkerPop图计算框架的一部分。它主要用于在图结构数据(如社交网络、推荐系统、知识图谱)中执行复杂的遍历和查询操作。Gremlin的核心优势在于其灵活性和表达能力,允许开发者通过链式组合操作符来构建路径式查询,从而高效地处理点(Vertex)和边(Edge)的关系[^1][^2]。下面我将逐步介绍Gremlin的关键方面,帮助您理解其基本原理和应用。 #### 1. **核心特性** - **函数式编程风格**:Gremlin采用函数式编程范式,通过将多个遍历操作符(如`out()`、`in()`、`has()`)链式组合,形成一条查询路径。例如,查询“从Hercules出发,遍历到他的父亲,再到他父亲的父亲,最后返回祖父的名字”可以简洁地表达为一个表达式链[^2]。这种设计使得查询逻辑直观且易于扩展。 - **路径式表达式**:Gremlin查询类似于在图中“行走”,每一步操作都会生成一个新的状态(traversal),最终返回所需结果。这支持复杂的关系查询,如多跳遍历(multi-hop traversal)[^2]。 - **灵活性与通用性**:Gremlin不绑定于特定图数据库系统(如Neo4j、JanusGraph),而是作为通用接口,适用于各种图数据库后端。它注重表达能力和灵活性,适用于需要动态查询的场景[^1][^4]。 #### 2. **图结构基础** 在图数据库中,数据模型由“点”(Vertex)和“边”(Edge)组成: - **点(Vertex)**:代表实体(如用户、产品),在Gremlin中通过`V()`操作符创建或查询。例如,创建一个点的基本语法是`g.addV('person').property('name', 'Alice')`,其中`g`是图遍历的起点[^3]。 - **边(Edge)**:连接两个点,表示关系(如朋友关系、购买关系)。创建边的示例为`g.V(Alice).addE('knows').to(g.V(Bob))`[^3]。 这种结构不同于关系型数据库的表模型,Gremlin通过遍历操作直接处理这些元素,避免复杂的JOIN操作[^4]。 #### 3. **与其他图查询语言的比较** Gremlin与其他主流图查询语言(如Cypher、SPARQL)存在差异: - **Cypher**(Neo4j使用):注重易用性和可视化,语法更接近自然语言,但表达能力不如Gremlin[^1]。 - **SPARQL**(用于RDF图):强调查询复杂性和标准兼容性,适合语义网应用,但学习曲线较陡[^1]。 - **GQL**(正在制定的国际标准):旨在统一图查询语言,但目前尚未成熟,Gremlin在通用性和灵活性上更具优势[^4]。 总体而言,开发者选择Gremlin时,通常基于其对复杂遍历的支持和跨平台兼容性[^1][^4]。 #### 4. **简单查询示例** 以下是一个Gremlin查询示例,演示如何从一个点开始遍历关系: ```groovy // 假设图中有Hercules和他的家族关系 g.V().has('name', 'Hercules') // 找到名为Hercules的点 .out('father') // 遍历到他的父亲 .out('father') // 遍历到父亲的父亲(祖父) .values('name') // 返回祖父的名字 ``` 这个查询链式组合了多个操作,清晰地表达了路径逻辑,体现了Gremlin的函数式风格[^2]。在实际中,Gremlin支持多种编程语言绑定(如Java、Python),便于集成到应用中。 #### 总结 Gremlin作为图数据库查询语言,以其强大的遍历能力和灵活性著称,特别适合处理深度关系查询。尽管图查询语言领域尚未统一标准(GQL仍在制定中),但Gremlin已在工业界广泛应用,如社交网络分析和推荐系统[^4][^5]。如果您有具体数据库或场景,可以进一步探讨优化方法(如索引使用)[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值