[关闭]
@gzm1997 2018-11-05T11:47:58.000000Z 字数 3321 阅读 1249

cayley原理2

cayley


cayley查询过程

cayley的查询过程相当复杂 下面是我个人的学习结果 仅仅是个人看法 无法保证绝对正确
微信图片_20180820172126.png-16.9kB


构造态射数组

在cayley中的查询一般我们都是构造一个path结构体实例 例如查询从A出发 经过节点12 可以达到什么节点

p := cayley.StartPath(store, quad.String("A")).Out(quad.Int(12))

上面的语句实质上返回一个path实例 就是p 对于我们用来查询的结构path

  1. type Path struct {
  2. stack []morphism
  3. qs graph.QuadStore // Optionally. A nil qs is equivalent to a morphism.
  4. baseContext pathContext
  5. }

上面有一个重要的字段

stack       []morphism

morphism态射在范畴论中就是一个函数变换的抽象过程 cayley中的态射我们可以理解是我们每一个out int has等等指向下一个节点迭代的函数封装 我们每一个指向下一个的迭代(in out等)都转换为一个morphism态射 然后存在path中的stack**态射数组**

这个stack存储着表示我们查询的每一个划分(out in has等等)的态射

每一个态射在cayley中的定义

  1. type morphism struct {
  2. IsTag bool
  3. Reversal func(*pathContext) (morphism, *pathContext)
  4. Apply applyMorphism
  5. tags []string
  6. }

举一个简答的例子 也是上面那个例子

p := cayley.StartPath(store, quad.String("A")).Out(quad.Int(12))

上面这条查询语句在声明了一个path结构体的同时 也构造出我们上面所说的态射数组
下面的绿色大框即为我们的态射数组stack 两个蓝色框即为我们数组中的两个态射 都是morphism结构体 但是我们可以看红色框框 他们的apply这个函数是不一样的 一个是isMorphism 一个outMorphism

微信图片_20180820155549.png-45.6kB

我们可以很容易理解为什么有outMorphism态射 但是不能理解为什么有isMorphism这个态射 其实isMorphism是初始化的态射


构造shape

shape顾名思义就是我们查询路径的一种表现形式 表示了我们使用path查询始末的一条抽象路径 如上面的查询抽象的一个shape就是

A -> 12 ->

shape在cayley中只是一个接口 但凡实现了这个接口中的方法的结构体都是shape 具体的形式非常多样和复杂 我们这里不做详细研究 shape接口定义如下

  1. // Shape represent a query tree shape.
  2. type Shape interface {
  3. // BuildIterator constructs an iterator tree from a given shapes and binds it to QuadStore.
  4. BuildIterator(qs graph.QuadStore) graph.Iterator
  5. // Optimize runs an optimization pass over a query shape.
  6. //
  7. // It returns a bool that indicates if shape was replaced and should always return a copy of shape in this case.
  8. // In case no optimizations were made, it returns the same unmodified shape.
  9. //
  10. // If Optimizer is specified, it will be used instead of default optimizations.
  11. Optimize(r Optimizer) (Shape, bool)
  12. }

一个具体的shape的例子 可见shape的具体类型和机构是很多样的 没必要具体研究
微信图片_20180820162647.png-31.5kB

可以看到下面 随着态射一个一个被执行 我们的到的构造出来的shape也是变化的 每一次态射之后的到的shape都作为参数传入下一个被执行的态射函数 shape不断积累 不断拓张 最终形成我们需要的查询路径
微信图片_20180820162145.png-17.3kB

构造shape部分还包含了大量的shape优化 这部分复杂而内容很多 这里不展开


构造迭代器和迭代链

Iterator迭代器这个概念我们可以理解只负责某一部分计算工作的组件 cayley的查询设计是由若干个迭代器嵌套或者依次排列组合成的 呈现一个分布式结构 组合成的最终迭代器叫做IterateChain迭代器链 跟上面的shape一样 迭代的种类也是多种多样的 在这个分布式结构中的迭代器种类也不是都是类型一样的 所以宏观上我们不必关系具体使用了何种迭代器

cayley中对于迭代器的声明也是一个接口 在cayley中但凡实现了这个接口中所有方法的结构体我们都统称为迭代器Iterator

  1. type Iterator interface {
  2. String() string
  3. Tagger() *Tagger
  4. TagResults(map[string]Value)
  5. Result() Value
  6. Next(ctx context.Context) bool
  7. NextPath(ctx context.Context) bool
  8. Contains(ctx context.Context, v Value) bool
  9. Err() error
  10. Reset()
  11. Clone() Iterator
  12. Stats() IteratorStats
  13. Size() (int64, bool)
  14. Type() Type
  15. Optimize() (Iterator, bool)
  16. SubIterators() []Iterator
  17. Close() error
  18. UID() uint64
  19. }

上面最重要的迭代器方法就是

Next方法被这个迭代器用来执行内嵌在它自己内部的另一个迭代器 Result这个函数用来获取执行结果

那么我们会很好奇迭代器这么抽象是怎样最终转化为mongodb的查询语句的呢?因为在cayley中使用的mongodb连接第三方包就是mgo.v2

其实我们知道迭代是一层一层嵌套的 那么我们可以看一下最底层的迭代器的结构 最底层的迭代器如下

  1. type Iterator struct {
  2. uid uint64
  3. tags graph.Tagger
  4. qs *QuadStore
  5. collection string
  6. limit int64
  7. constraint []FieldFilter
  8. links []Linkage // used in Contains
  9. iter DocIterator
  10. result graph.Value
  11. size int64
  12. err error
  13. }

这个迭代是位于cayley源代码中的nosql\iterator.go中声明的迭代器 其中我们可以看到它包含一个字段

constraint []FieldFilter

FieldFilter在cayley定义如下

  1. // FieldFilter represents a single field comparison operation.
  2. type FieldFilter struct {
  3. Path []string // path is a path to specific field in the document
  4. Filter FilterOp // comparison operation
  5. Value Value // value that will be compared with field of the document
  6. }

Filter FilterO是一个用来表示比较的字段 有

Value Value就是存储的节点值

语义上 上面这个结构体可以根据比较大小的操作符FilterOp和它的值value 来转化为在mongodb中对图的具体某个节点的查询

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注