• google Cayley图谱数据库初试


    一.安装

    mkdir cayley

    cd cayley

    mkdir src

    export GOPATH=$(pwd)

    go get github.com/google/cayley

    go build src/github.com/google/cayley/cayley.go

    其中缺什么包下什么包,没有hg工具安装hg

    修改下源码cayley.go 

    复制代码
        switch cmd {
        case "init":
            db.Init(cfg, *tripleFile)
        case "load":
            ts, _ = db.Open(cfg)
            db.Load(ts, cfg, *tripleFile)
            ts.Close()
        case "repl":
            ts, _ = db.Open(cfg)          
            db.Repl(ts, *queryLanguage, cfg)
            ts.Close()
        case "http":
            ts, _ := db.Open(cfg)
            http.Serve(ts, cfg)
            ts.Close()
        default:
            fmt.Println("No command", cmd)
            flag.Usage()
        }
    复制代码

    运行

     go build $GOPATH/src/github.com/google/cayley/cayley.go && ./cayley http --port=8080 --assets=$GOPATH/src/github.com/google/cayley --dbpath=src/testdata.nt

    assets 参数代表启动http server以后存放html静态资源的目录,源码里是自带的

    dbpath 是数据库的一些初始化数据,必须指定,不然启动了,也没法添加数据,默认是指定为/tmp/testdb文件

    在浏览器输入http://127.0.0.1:8080/如果有页面输出说明成功了

     

    二.基本概念

    testdata.nt内容如下

    复制代码
    alice follows bob .
    bob follows alice .
    charlie follows bob .
    dani follows charlie .
    dani follows alice .
    alice is cool .
    bob is "not cool" .
    charlie is cool .
    dani is "not cool" .
    复制代码

    内容的每行都是以空格分隔的四元组,每一行叫做一个Triple,存储多个Triple组成了TripleStore,每个Triple由四部分组成,依次对应数据每行用空格分隔的每项,分别叫Subject,Predicate,Object,Provenance。对应中文里的,Subject是中文里的主语,Predicate是中文里的谓语,Object是宾语,Provenance是来源。也就是说,每行描述了,谁怎么样了XX,或者谁是XX样的。Subject转换成有向图中的顶点,Object是出度的顶点,Predicate是路径。

    cayley搭了一套图数据库的框架,官方提供了三种存储memory,leveldb,mongodb 可以切换存储引擎,只需要实现接口,就可以扩展存储方式,和mysql与innodb的关系差不多。

    三.使用API

    1. g.V()

    取一个图中的顶点,也就是Triple中的Subject,返回一个点的对象

    2. path.Out([predicatePath], [tags])

    Out是取一个顶点的出度。不过,这个出度是按照谓词区分的,当Out()不传递参数的时候,是取出某个顶点不按路径区分的所有出度;当Out传递了predicatePath参数的时候,是取出某个顶点,在某个路径上的所有出度。tags 是用来存储路径的名称。例如:

    我们入库的数据中以alice顶点为例,

    alice follows bob
    alice is cool

    可以看出alice这个顶点有两个路径,分别是follows和is

    (1) 查询allice的所有出度

    g.V("alice").All()

    (2) 查询alice的关注:

    g.V("alice").Out("follows").All()

    (3) 查询allice是否很cool

    g.V("alice").Out("is").All() 

    (4) 查询alice的关注和是否很cool

    复制代码
    g.V("alice").Out(["follows", "is"]).All()

    "
    result": [ { "id": "bob" }, { "id": "cool" } ] 
    复制代码

    (5) 虽然你可以直观的看到,alice的关注是bob,并且alice是个很酷的人,那是因为是通过字面意思,比如有些人follows为空,有些人is为空,那就没法判断返回的出度在哪个路径上,这个时候应该使用tag参数

    g.V("alice").Out(["follows", "is"], "path").All()

    3. path.In([predicatePath], [tags])

    和Out正好相反,是求的入度。

    (1) 求所有cool的人

    g.V("cool").In("is").All()

    (2) alice的粉丝

    g.V("alice").In("follows").All()

    4. path.Both([predicatePath], [tags])

    In和Out的的结果并集,没有去重

    5. path.Has(predicate, object)

    反向查找,paredicate是路径,object是三元组中的宾语

    (1) 查找alice的粉丝

    g.V().Has("follows", "alice").All()

    6.path.Follow(morphism)

    通过管道加速

    g.V().Has("name","Casablanca") .Out("/film/film/starring").Out("/film/performance/actor") .Out("name").All()

    等价于

    var filmToActor = g.Morphism().Out("/film/film/starring").Out("/film/performance/actor")

    g.V().Has("name", "Casablanca").Follow(filmToActor).Out("name").All()

    总体的查询模式就是,选顶点,选路径,ALL输出 

    四. Triple,基于内存的TripleStore数据结构

    1.数据结构

    type Triple struct {
      Subject string
      Predicate string
      Object string 
      Provenance string
    }

    三元组,Provenance好像是类似于数据库里的分库的概念(不大确定),Triple中不同的字段,在后面叫Direction

    复制代码
    type TripleStore struct {
      idCounter int64           //idMap的长度     
      tripleIdCounter int64        //tripleId的序列
      idMap map[string]int64       //存储三元组的 内容->tripleId 的对应关系
      revIdMap map[int64]string     //存储三元组的 tripleId->内容 的对应关系 idMap的反向映射关系
      triples []graph.Triple       //存储每条记录的关系三元组
      size int64              //triples的数量
      index TripleDirectionIndex    //triples的索引 每个idMap中的一个key有一个平衡二叉树,里面放了tripleId
    }
    复制代码

      

    复制代码
    TripleDirectionIndex是一个通过Direction作为分组的一级索引
    type TripleDirectionIndex struct {
        subject    map[int64]*llrb.LLRB  
        predicate  map[int64]*llrb.LLRB
        object     map[int64]*llrb.LLRB
        provenance map[int64]*llrb.LLRB
    }
    复制代码

     2.实例演示

    数据

    alice follows bob .

    bob follows alice .

    charlie follows bob . 

     

    建立以后的结果如下

              idMap                            revIdMap

              1 <=============> alice

              2 <=============> follows

              3 <=============> bob

              4 <=============> charlie

     

                      triples

          Direction  DirectionSubject  DirectionPredicate   DirectionObject

    tripleId  1       alice        follows        bob

           2       bob         follows        alice

           3       charlie         follows        bob  

     

                      DirectionIndex

                                     1  =========>  (1)

            DirectionSubject=============>     3  =========>  (2)

                                   4  =========>  (3)      

     

            DirectionPredicate============>     2  =========>      插入第一行时(1)    --->  插入第二行   (2)                                                                              /  

                                                                (1)

                                                

                                                 -----> 插入第三行    (2)

                                                          /  

                                                        (1)      (3)

     

            DirectionObject==============>   3  ============>  插入第一行 (1) ---> 插入第三行 (3)

                                                              /

                                                             (1)

                                   1 =============> (2)

     

    DirectionIndex中的1 是IdMap中的编号,(1)是triples中的tripleId

     

    3.查询方法

    看源码里把查询逻辑都写在了itorator里,各种hasA,and,or,link!@#!4。

    如果查一个值的入度就是先查DirectionObject索引,查出度就查DirectionSubject索引,有路径条件就再在DirectionPredicate里做二分排除掉。

     

    原文地址:https://www.cnblogs.com/23lalala/p/3865485.html
  • 相关阅读:
    WPF样式之画刷结合样式
    年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)
    30分钟学会XAML
    spring注解之@Import注解的三种使用方式
    大白话讲解Spring的@bean注解
    SpringBoot中的五种对静态资源的映射规则
    Spring注解之@Autowired、@Qualifier、@Resource、@Value
    Spring中如何使用工厂模式实现程序解耦?
    Spring注解之@Component、@Controller、@Service、@Repository
    Spring整合Redis
  • 原文地址:https://www.cnblogs.com/jpfss/p/11555582.html
Copyright © 2020-2023  润新知