Neo4j学习笔记(一) 数据库知识

语法约定
 • 节点别名用小写驼峰(以小写字母开头)
 • 标签用大写驼峰(以大写字母开头)
 • 关系用蛇形大写(类似 ACTED_IN)
 • 属性名用 小写驼峰
 • 关键词全部用大写

Cypher的语法
  https://neo4j.com/docs/pdf/cypher-refcard-4.0.pdf
  CYPHER中的表达式如下:
    十进制(整型和双精度型)的字面值:13、-4000、3 14、6.022E23
    十六进制整型字面值(以0x开头):0x13zf、0xFC3A9、-0x66eff
    八进制整型字面值(以0开头):01372、02127、-05671
    字符串字面值:'Hello'、"World"
    布尔字面值:true、false、TRUE、FALSE
    变量:n、x、rel、myFancyVariable、`A name with weird stuff in it[]!`
    属性:n.prop、x.prop、rel.thisProperty、myFancyVariable.`(weird property name)`
    动态属性:n["prop"]、rel[n.city +n.zip]、map[coll[0]]
    参数:$param、$0
    表达式列表: ['a','b']、[1,2,3]、[a,2,n.property,$param]、[]
    函数调用:length(p)、nodes(p)
    聚合函数:avg(x.prop)、count(*)
    路径-模式:(a)-->()<--(b),(a)->[r:`TYPE A1`|TYPE2]->(b),(a)->[:TYPE1*1..4]->(b)
    计算式:1+2 and 3<4
    返回true或者false的断言表达式:a.prop = 'Hello'、length(p)>10、exists(a.name)
    正则表达式:a.name =~'Tob.*'
    大小写敏感的字符串匹配表达式:a.surname STARTS WITH 'Sven'、a.surname ENDS WITH 'son' or a.surname CONTAINS 'son'.
    CASE表达式
      CASE test/
      WHEN value/predicate THEN result
      [WHEN ...]
      [ELSE default]
      END
  转义符
    \t,\b,\n,\r,\f,\',\",\\,\uxxxx,\uxxxxxxxx
    '
  运算符
    +,-,*,/,%,^
    =,<>,<,>,<=,>=,IS NULL,IS NOT NULL
    AND OR XOR NOT
    字符串连接用+,正则表达式匹配用=~
    列表的连接可以用+,检查存在用IN
  链式比较
    x<y<=z 等价于 x<y AND y<=z
    a op1 b op2 c ... y opN z 等价于 a op1 b and b op2 c and ... y opN z
  注释
    //
  列表
    range(0,10)  等于[0,1,2,3,4,5,6,7,8,9,10]
    range(0,10)[3] 等于 3
    range(0,10)[-3] 等于 8  索引负数时从后往前数,最后一个是-1
    range(0,10)[0..3] 等于[0,1,2] 不包含结束索引
    range(0,10)[0..-5] 等于[0,1,2,3,4,5] 不包含结束索引
    range(0,10)[-5..] 等于[6,7,8,9,10]
    range(0,10)[..4] 等于[0,1,2,3]
    range(0,10)[5..15] 等于[5,6,7,8,9,10] 索引越界的话就截断
    range(0,10)[15] 等于null
    size(range(0,10)[0..3]) 等于3
    [x in range(0,10) WHERE x%2 =0 | x^3] 等于 [0.0, 8.0, 64.0, 216.0, 512.0, 1000.0]
    [x in range(0,6) WHERE x%2 =0] 等于 [0, 2, 4, 6]
    MATCH(a:Person{ name: 'Tom Hanks'}) RETURN [(a)-->(b) WHERE b:Movie | b.released] AS years 输出参演电影的发行时间
  Map投射
    MATCH (actor:Person{name: 'Tom Hanks'})-[:ACTED_IN]->(movie:Movie) RETURN actor{.name,movies:collect(movie{.title,.released})}
      返回构建好的Map结构
    MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie) WITH actor, count (movie) As nrOfMovies RETURN actor {.name, nrOfMovies}
      变量映射,属性名为nrOfMovies
    MATCH (actor: Person{name: 'Tom Hanks'})RETURN actor{ .*, .age }
      返回所有属性,age属性不存在,投射为age:null
  null
    大多数以null作为输入的表达式都返回null
    返回空值的表达式
      从列表中获取不存在的元素:[][0],head([l])
      试图访问节点或者关系的不存在的属性:n.missingProperty
      与null做比较:1<null
      包含null的算术运算:1 +null
      包含任何null参数的函数调用: sin(null)
  最短路径
    match (p1:Person{name:'Tom Hanks'}),(p2:Person{name:'Meg Ryan'}),p=shortestPath((p1)-[*]-(p2))
    where NONE(r IN relationships(p) WHERE type(r)='FATHER') return p;
      找出两个人的最短关系路径,路径上的关系不包括FATHER
    allShortestPaths()可以返回所有最短路径
  OPTINAL MATCH相当于外联结,匹配不到返回null
    MATCH (a:Movie{title:'The Matrix'})
    OPTIONAL MATCH (a)-[r:ACTED_IN]->(b)
    RETURN a,r,b,b.name
      r,b,b.name都返回null
  从Cyper3.2开始START语句已经被废弃
  聚合函数
    count,sum,avg,max,min
    percentileDisc(x.prop,percent) 计算给定值在组中的百分位,percent:0.0-1.0,舍入法返回最接近百分位的值
    percentileCont(x.prop,percent) 计算给定值在组中的百分位,percent:0.0-1.0,线性插值法在两个值之间计算一个加权平均数
    stdev,stdevp 计算标准差
    collect 将所有值收集起来放入一个列表,空值null将被忽略
    distinct
  MERGE匹配到就直接取,否则就新建
    MERGE (p:Person{name:'name1',age:12} ON CREATE SET p.created=timestamp() ON MATCH p.lastSeen=timestamp()
      如果创建做什么如果匹配到做什么
    当 MERGE应用于整个模式时,要么全部匹配上,要么全部新创建。
      MATCH (oliver:Person{name:'Oliver Stone'),(reiner:rerson{name:'Reiner'})
      MERGE (oliver)-[:DIRECTED]->(movie:Movie)<-[:ACTED_IN]-(reiner)
      RETURN movie
        如果oliver和reiner没有合作过,会创建一个新的Movie
    MERGE (oliver:Person{name: '0liver Stone',role: 'Gordon Gekko'}) RETURN oliver
      如果匹配不到想要创建时与唯一性约束冲突的话,会执行失败
    MERGE (person:Person{name: $param.name, role: $param.role )RETURN person.name, person.role
      参数使用要指定到字段
  SET
    SET n.prop = null 等价于 REMOVE n.prop
    SET n1 = n2 完全复制n2到n1
    SET n1 += {p1:value1,p2:value2} 添加两个属性
    SET n.prop = $param 使用参数赋值属性
    SET n = $param 使用参数赋值节点
    SET n.p1=value1,n.p2=value2 设置多个属性
    SET n:LABEL1:LABEL2 给节点设置标签
  DELETE
    MATCH(n) DETACH DELETE n 删除节点和关系
  REMOVE
    REMOVE n.prop 删除属性
    REMOVE n:LABEL1:LABEL2 删除节点的多个标签
  FOREACH用于更新列表中的数据
    MATCH p = (begain)-[*]->(END) WHERE begain.name='A' AND END.name='D'
    FOREACH(n IN nodes(p) | SET n.marked=TRUE)
      为路径上的节点设置属性
    MATCH (a:Person {name: "A"})
    FOREACH(name IN ["Mike","Carl","Bruce"] | CREATE(a)-[:FRIEND]->(:Person {name: name}))
      通过列表添加朋友
  CREATE UNIQUE
    语句相当于MATCH 和 CREATE的混合体—尽可能地匹配,然后创建未匹配到的
    和MERGE非常相似,但无法创建关系中的起始节点
      MATCH (root { name: 'A' })
      CREATE UNIQUE (root)-[r:KNOWS{name1:'ab12'}]-(leaf{name:'D'})
      RETURN leaf
        如果r和leaf都能匹配到,则直接返回,否则创建r和leaf
  RETURN
    可以返回节点,关系,路径,属性和其他表达式
      MATCH (a{name: 'A'})
      RETURN a.age > 30,"I'ma literal",(a)-->()
  ORDER BY
    紧跟RETURN或者WITH语句
    当结果集中包含null 值时,对于升序排列,null总是在结果集的末尾。而对于降序排序,null值总是排在最前面。
  SKIP LIMIT
    MATCH (n) RETURN n ORDER BY n.name SKIP 1 LIMIT 2 跳过第1个取第2,3个
  WITH
    WITH语句将分段的查询部分连接在一起,查询结果从一部分以管道形式传递给另外一部分作为开始点。
    使用WITH可以在将结果传递到后续查询之前对结果进行操作。操作可以是改变结果的形式或者数量。
    WITH的一个常见用法就是限制传递给其他MATCH语句的结果数。通过结合ORDER BY和LIMIT,可获取排在前面的X个结果。
    另一个用法就是在聚合值上过滤。WITH用于在 WHERE 断言中引入聚合。这些聚合表达式创建了新的结果绑定字段。WITH 也能像RETURN 一样对结果使用别名作为绑定名。WITH 还可以用于将图的读语句和更新语句分开,杳询中的每一部分要么只是读取,要么都是写入。当写部分的语句是基于读语句的结果时,这两者之间的转换必须使用WITH.
    聚合的结果必须要通过WITH语句传递才能进行过滤
      MATCH (david { name: 'Tom Hanks' })--()--(otherPerson)
      WITH otherPerson, count(*) AS foaf
      WHERE foaf > 1
      RETURN otherPerson
    可以在将结果传递给collect函数之前对结果进行排序,这样就可以返回排过序的列表。
      MATCH (n)
      WITH n
      ORDER BY n.name DESC LIMIT 3
      RETURN collect(n.name)
    可以限制匹配路径的数量,然后以这些路径为基础再做任何类似的有限制条件的搜索。
      MATCH (n { name: 'Tom Hanks' })--(m)
      WITH m
      ORDER BY m.name DESC LIMIT 1
      MATCH (m)--(o)
      RETURN o.name
  UNWIND
    UNWIND将一个列表展开为一个行的序列
    使用DISTINCT将一个重复值列表转为一个集合
      WITH [1, 1, 2, 2] AS coll
      UNWIND coll AS x
      WITH DISTINCT x
      RETURN collect(x) AS SET
  UNION
    UNION语句用于将多个查询结果组合起来。使用UNION组合查询的结果时,所有查询到的列的名称和数量必须完全一致。
    用UNION ALL将两个查询的结果组合在一起,可能包含重复行。
    在UNION中不使用ALL时,组合的结果集中会去掉重复值。
  CALL
    CALL db.propertyKeys() YIELD propertyKey AS prop
    MATCH (n)
    WHERE n[prop] IS NOT NULL
    RETURN prop, count(n) AS numNodes
      调用内嵌过程db.propertyKeys作为一部分,计算数据库中包含每个属性键的节点数
  函数
    断言(Predicate)函数
      all(variable IN list WHERE predicate) 判断是否一个断言适用于列表中的所有元素
        MATCH p =(a)-[*1..3]->(b)
        WHERE ALL (x IN nodes(p) WHERE x.age > 30)
        RETURN p
          返回路径中的所有节点都有一个至少大于30的age属性
      any(variable IN list WHERE predicate) 判断是否一个断言至少适用于列表中的一个元素
        MATCH (a)
        WHERE ANY (x IN a.array WHERE x = 'one')
        RETURN a
          返回路径中的所有节点的array数组属性中至少有一个值为'one'
      none(variable IN list WHERE predicate) 如果断言不适用于列表中的任何元素,则返回true
        MATCH p =(n)-[*1..3]->(b)
        WHERE n.name = 'Alice' AND NONE (x IN nodes(p) WHERE x.age = 25)
        RETURN p
          返回路径中没有节点的age属性值为25
      single(variable IN list WHERE predicate) 如果断言刚好只适用于列表中的某一个元素,则返回true
        MATCH p =(n)-->(b)
        WHERE n.name = 'Alice' AND SINGLE (var IN nodes(p) WHERE var.eyes = 'blue')
        RETURN p
          每条返回的路径中刚好只有一个节点的eyes属性值为'blue'
      exists( pattern-or-property ) 存在该模式或者节点中存在该属性时,则返回true
        MATCH (n)
        WHERE exists(n.name)
        RETURN n.name AS name, exists((n)-[:MARRIED]->()) AS is_married
    标量(Scalar)函数
      size(list) 使用size()返回列表中元素的个数
      size(pattern expression) 模式表达式匹配到的查询结果集的个数
        MATCH (a)
        WHERE a.name = 'Alice'
        RETURN size((a)-->()-->()) AS fof
          返回了模式表达式匹配到的子图的个数
      length(string) 字符串的长度
      length(path) 路径的长度
      type(relationship) 关系类型
      id(property-container) 关系或者节点的id
      coalesce(expression[, expression]*) 返回表达式列表中的第一个非空的值。如果所有的实参都为空 ,则返回null。
      head(expression) 返回列表中的第一个元素
      last(expression) 返回列表中的最后一个元素
      timestamp() 返回当前时间与1970年1月1日午夜之间的差值,单位以毫秒计算。它在整个查询中始终返回同一个值,即使是在一个运行时间很长的查询中。
      startNode(relationship) 返回一个关系的开始节点
      endNode(relationship) 返回一个关系的结束节点
      properties(expression) 将实参转为属性值的map。如果实参是一个节点或者关系,返回的就是节点或关系的属性的map。如果实参已经是一个map了,那么原样返回结果。
      toInteger(expression) 字符串会被解析为一个整数。如果解析失败,将返回null。浮点数将被强制转换为整数。
      toFloat(expression) 字符串会被解析为一个浮点数。如果解析失败,将返回null。整数将被强制转换为浮点数。
    列表(List)函数
      nodes(path) 返回路径中的所有节点
      relationships(path) 返回路径中的所有关系
      labels(node) 返回节点的所有标签
      keys(property-container) 返回一个节点,关系或者map的所有属性名
      extract(variable IN list | expression) 从节点或关系列表中返回单个属性或者某个函数的值
        MATCH p=(a)-->(b)-->(C)
        WHERE a.name = 'Alice' AND b.name = 'Bob' AND c.name = 'Daniel'
        RETURN extract(n IN nodes(p) | n.age) AS extracted
      filter(variable IN list WHERE predicate) 返回列表中满足断言要求的所有元素
      tail(expression) 返回列表中除了首元素之外的所有元素
      range(start,end[,step]) 返回某个范围内的数值。值之间的默认步长为1,范围包含起始边界值。
      reduce(accumulator = initial, variable IN list | expression )
        对列表中的每个元素执行一个表达式,将表达式结果存入一个累加器
        MATCH p=(a)-->(b)-->(c)
        WHERE a.name = 'Alice' AND b.name = 'Bob' AND c.name = 'Daniel'
        RETURN reduce(totalAge = 0,n IN nodes(p)| totalAge + n.age) AS reduction
          对路径p中的所有节点,计算各个节点的age值的和
    数学函数
      abs(expression) 绝对值
      ceil(expression) 大于等于参数的最小整数,进位取整
      floor(expression) 小于等于参数的最大整数,舍位取整
      round(expression) 四舍五入
      sign(expression) 数值为正返回1,负返回-1,0返回0
      rand() [0,1)之间的随机数
      log(expression) 自然对数
      log10(expression) 常用对数(以10为底)
      exp(expression) e的n次方,n为表达式的值
      e() 自然对数的底
      sqrt(expression) 平方根
      sin(expression) 正弦函数
      cos(expression) 余弦函数
      tan(expression) 正切函数
      cot(expression) 余切函数
      asin(expression) 反正弦函数
      acos(expression) 反余弦函数
      atan(expression) 反正切函数
      atan2(expression1,expression2) 方位角,也可以理解为计算复数x+yi 的幅角
      pi() PI的数值
      degrees(expression) 将弧度转为度
      radians(expression) 将度转为弧度
      haversin(expression) 半正矢
    字符串函数
      replace(original,search,replace)
      substring(original,start[,length])
      left(original,length)
      right(original,length)
      ltrim(original)
      rtrim(original)
      trim(original)
      lower(original)
      upper(original)
      split(original,splitPatten)
      reverse(original)
      toString(original)
  索引与约束
    CREATE INDEX ON :Person(name) 在拥有某个标签的所有节点的某个属性上创建索引
    DROP INDEX ON :Person(name)
    CREATE CONSTRAINT ON (p:Person) ASSERT p.identifier IS UNIQUE 创建唯一约束,会自动添加对应字段的索引
    DROP CONSTRAINT ON (p:Person) ASSERT p.identifier IS UNIQUE
    CREATE CONSTRAINT ON (b:Book) ASSERT exists(b.isbn) 创建节点属性必须存在的约束,社区版不支持
    DROP CONSTRAINT ON (b:Book) ASSERT exists(b.isbn)
    CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists (like.day) 创建关系属性必须存在的约束,社区版不支持
    DROP CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists (like.day)

APOC
  找到与neo4j匹配的版本下载
  下载地址:https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases
  放到neo4j的plugins目录,重启neo4j
  
  打开使用apoc函数和过程的权限:
    conf/neo4j.conf
      dbms.security.procedures.unrestricted=apoc.*
  -->neo4j-community-4.0.7没有设置这个也可以用?

  随机图生成
  CALL apoc.generate.ba(1000, 2, 'Person', 'FRIEND_OF')
  // 重命名标签
  CALL apoc.refactor.rename.label(oldLabel,newLabel,[nodes])
  // 重命名关系类型
  CALL apoc.refactor.rename.type(oldType,newType,[rels])
  // 重命名节点属性
  CALL apoc.refactor.rename.nodeProperty(oldName,newName,[nodes])
  // 重命名关系属性
  CALL apoc.refactor.rename.typeProperty(oldName,newName,[rels]) 
  // 合并节点
  CALL apoc.refactor.mergeNodes([node1,node2],[{properties:'overwrite' or 'discard' or 'combine'}])
  // 反转关系
  CALL apoc.refactor.invert(rel)
  // 改变关系类型
  CALL apoc.refactor.setType(rel, 'NEW-TYPE')
  // 改变关系的开始节点
  CALL apoc.refactor.from(rel, startNode)
  // 改变关系的结束节点
  CALL apoc.refactor.to(rel, endNode)
  // 添加标签
  CALL apoc.create.addLabels([node,id,ids,nodes],['Label',...])

性能优化
  执行计划
    Explain 会给出查询的执行计划,但不会执行查询
    Profile 将执行查询井返回结果
  运算符
    全节点扫描(AllNodesScan)
    标签扫描(LabelScan)
    节点索引查找(NodeIndexSeek)
    节点索引范围查找(NodeIndexSeekByRange) 使用STARTS WITH,>,<,>=,<=的时候
    节点索引扫描(NodeIndexScan) 索引扫描将遍历存储在索引中的所有值,它可以找到拥有特定标签和特定属性的所有节点(如exists(n.prop))
    节点索引包含扫描(NodeIndexContainsScan) 使用CONTAINS的时候
    ID查找节点(NodeByIdSeek)
    ID查找有向关系(DirectedRelationshipByIdSeek)
    ID查找无向关系(UndirectedRelationshipByIdSeek)
    Expand(All)
      给定一个开始节点,expand-all将根据关系中的模式沿开始节点或结束节点展开。它也能处理变长模式的关系。
    Expand(Into)
      当开始和结束节点都已经找到时,expand-into用于找到两个节点之间连接的所有关系。
    OptionalExpand(All)
      使用OPTIONAL MATCH时
    组合运算符
      ......
    行运算符
      ......
    更新运算符
      ......
    因为查询计划会被系统缓存下来,所以最好使用参数而不是常量值
  索引
    创建
      CREATE INDEX ON :LabelName(propertyName)
    创建有约束的属性会自动创建索引
    查询
      CALL db.indexes
      :schema ls -l :YourLabel
    强制使用索引
      MATCH (t:Tower {name:””})
      USING INDEX t:Tower(name)
      RETURN t
    强制使用标签
      MATCH (t:Location:Tower)
      USING SCAN t:Tower
      WHERE t.country="JPN"
      RETURN t
    连接提示
      MATCH (liskov:Scientist { name:'Liskov'})-[ :KNOWS]->(wing:Scientist{ name :'Wina'})-[:RESEARCHED]->(cs:Science { name :'Computer Science'})<-[:RESEARCHED]-(liskov)
      USING INDEX liskov:scientist (name)
      USING JOIN ON liskov,cs
      RETURN wina .born As column

  规则
    Explain所有查询
    行数从上向下应该是快速递减的。如果不是,考虑使用了足够的标签吗、创建足够多的索引了吗、我们使用的属性上面建索引了吗?
    不要过度消耗资源。如果只想使用节点中的一些属性,就不要将整个节点全部返回。
    尽量不要做笛卡儿积查询。
    避免意外出现笛卡儿积的好方法就是用WITH命令把查询切成几块。WITH允许将变量从一块传到另外一块。我们可以传递节点、列表或者值到另外一个语句块。

数据导入
  导入csv文件
    Cypher方式
      文件路径:
        'file:///'开头的路径表示import目录开始的路径
        'file:'表示绝对路径
        'http://'网络路径
      表头
        csv有表头时,可以使用第一行的每列内容做为字段名,可以使用`abc aa`的方式引用带空格的字段
        csv没有表头行时,可以使用row[0],row[1]的方式进行字段的引用
      类型
        可以使用toInt(),toFloat(),toBoolean()等类型转换函数
      // clear data
      MATCH (n)
      DETACH DELETE n;
      // Batch the import into sections with PERIODIC COMMIT
      :auto USING PERIODIC COMMIT 500
      // load Employee nodes
      LOAD CSV WITH HEADERS FROM 'file:///people.csv' AS row FIELDTERMINATOR ';'
      MERGE (e:Employee {employeeId: row.employeeId, name: row.Name})
      RETURN count(e);
      // load Company nodes
      LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
      WITH row WHERE row.Id IS NOT NULL
      WITH row,
      (CASE row.BusinessType
       WHEN 'P' THEN 'Public'
       WHEN 'R' THEN 'Private'
       WHEN 'G' THEN 'Government'
       ELSE 'Other' END) AS type
      MERGE (c:Company {companyId: row.Id, hqLocation: coalesce(row.Location, "Unknown")})
      SET c.emailAddress = CASE trim(row.Email) WHEN "" THEN null ELSE row.Email END
      SET c.businessType = type
      RETURN count(c);
      // create relationships
      LOAD CSV WITH HEADERS FROM 'file:///people.csv' AS row
      MATCH (e:Employee {employeeId: row.employeeId})
      MATCH (c:Company {companyId: row.Company})
      MERGE (e)-[:WORKS_FOR]->(c)
      RETURN *;

    大量导入时使用命令行
      neo4j-admin import [--mode=csv] [--database=<name>]
                         [--additional-config=<config-file-path>]
                         [--report-file=<filename>]
                         [--nodes[:Label1:Label2]=<"file1,file2,...">]
                         [--relationships[:RELATIONSHIP_TYPE]=<"file1,file2,...">]
                         [--id-type=<STRING|INTEGER|ACTUAL>]
                         [--input-encoding=<character-set>]
                         [--ignore-extra-columns[=<true|false>]]
                         [--ignore-duplicate-nodes[=<true|false>]]
                         [--ignore-missing-nodes[=<true|false>]]
                         [--multiline-fields[=<true|false>]]
                         [--delimiter=<delimiter-character>]
                         [--array-delimiter=<array-delimiter-character>]
                         [--quote=<quotation-character>]
                         [--max-memory=<max-memory-that-importer-can-use>]
                         [--f=<File containing all arguments to this import>]
                         [--high-io=<true/false>]

  导入JSON源
    用到时再学《Neo4j 3.x入门经典》P111
  导入JDBC源
    用到时再学《Neo4j 3.x入门经典》P114
  导入XML源
    用到时再学《Neo4j 3.x入门经典》P115

空间
  使用经纬度计算两地距离或者使用服务提供商的数据用地址计算两地间的距离
  用到时再学《Neo4j 3.x入门经典》第9章空间

用户和权限
  基础角色
    PUBLIC 只能改变密码和查看自己的信息
    reader 只读
    editor 可读写,只能使用已有数据结构,但是不能添加新的标签、关系类型和属性名
    publisher 可读写,能添加新的标签、关系类型和属性名
    architect 可读写,可以管理索引和约束
    admin

  // 切换到系统库
  :use system
  // 创建一个用户
  CALL dbms.security.createUser(username, password, requirePasswordChange)
    例子:CALL dbms.security.createUser('test1', 'test1', false)
  // 删除一个用户
  CALL dbms.security.deleteUser(username)
  // 修改指定用户密码
  CALL dbms.security.changeUserPassword(username, newPassword, requirePasswordChange)
  // 修改自己密码
  CALL dbms.security.changePassword(password, requirePasswordChange)
  // 列出所有用户
  CALL dbms.security.listUsers()
  // 赋予角色
  CALL dbms.security.addRoleToUser(roleName, username)
  // 收回角色
  CALL dbms.security.removeRoleFromUser(roleName, username)
  // 创建角色
  CALL dbms.security.createRole('newRoleName')
  // 删除角色
  CALL dbms.security.deleteRole(’newRoleName’)

  // 创建一个用户
  CREATE USER alice SET PASSWORD 'test1' CHANGE NOT REQUIRED
  // 挂起/激活用户
  ALTER USER alice SET STATUS SUSPENDED/ACTIVE
  // 修改自己密码
  ALTER CURRENT USER SET PASSWORD FROM $old TO $new
  // 列出所有用户
  SHOW USERS
  // 删除一个用户
  DROP USER alice

  // 创建角色复制另一个角色的权限
  CREATE ROLE my_second_role [IF NOT EXISTS] [AS COPY OF my_role]
  // 赋予角色
  GRANT ROLE my_role, my_second_role TO alice
  // 收回角色
  REVOKE ROLE my_second_role FROM alice
  // 列出所有角色
  SHOW ROLES
  // 列出使用中的角色和对应的用户
  SHOW POPULATED ROLES WITH USERS
  // 删除一个角色
  DROP ROLE my_role

  // 列出所有权限
  SHOW PRIVILEGES
  // 列出指定角色的权限
  SHOW ROLE my_role PRIVILEGES
  // 列出指定用户的权限
  SHOW USER alice PRIVILEGES
  // 赋予遍历所有图所有节点的权限
  GRANT TRAVERSE ON GRAPH * NODES * TO my_role
  // 拒绝读指定图的指定关系类型的指定字段
  DENY READ {prop} ON GRAPH foo RELATIONSHIP Type TO my_role
  // 赋予读和遍历包含指定标签节点的所有字段的权限
  GRANT MATCH {*} ON GRAPH foo ELEMENTS Label TO my_role
  // 收回所有图的写权限
  REVOKE WRITE ON GRAPH * FROM my_role
  // 赋予访问指定库的权限
  GRANT ACCESS ON DATABASE * TO my_role
  // 赋予启动停止指定库的权限
  GRANT START/STOP ON DATABASE * TO my_role
  // 赋予在指定库创建/删除索引的权限
  GRANT CREATE/DROP INDEX ON DATABASE foo TO my_role
  // 拒绝对指定库的索引管理
  DENY INDEX MANAGEMENT ON DATABASE bar TO my_role
  // 赋予在所有库创建/删除约束的权限
  GRANT CREATE/DROP CONSTRAINT ON DATABASE * TO my_role
  // 拒绝对所有库的删除约束
  DENY DROP CONSTRAINT ON DATABASE * TO my_role
  // 收回已经赋予或者拒绝的对所有库的创建/删除约束的权限
  REVOKE CONSTRAINT ON DATABASE * FROM my_role
  // 赋予在所有库新建标签的权限
  GRANT CREATE NEW LABELS ON DATABASE * TO my_role
  // 拒绝在指定库新建关系类型的权限
  DENY CREATE NEW TYPES ON DATABASE foo TO my_role
  // 收回(赋予在指定库新建属性名的权限)的权限
  REVOKE GRANT CREATE NEW PROPERTY NAMES ON DATABASE bar FROM my_role
  // 赋予在所有库创建标签/关系类型/属性名的权限
  GRANT NAME MANAGEMENT ON DATABASE * TO my_role
  // 赋予在指定库的所有库权限
  GRANT ALL ON DATABASE baz TO my_role

  // 赋予创建/删除角色的权限
  GRANT CREATE/DROP ROLE ON DBMS TO my_role
  // 拒绝赋予角色的权限
  DENY ASSIGN ROLE ON DBMS TO my_role
  // 拒绝收回角色的权限
  DENY REMOVE ROLE ON DBMS TO my_role
  // 收回(拒绝显示角色的权限)的操作
  REVOKE DENY SHOW ROLE ON DBMS FROM my_role
  // 赋予管理角色的权限
  GRANT ROLE MANAGEMENT ON DBMS TO my_role

图可视化
  组件库
    D3.js
    GraphViz
    Sigma.js
    Vivagraph.js
    yWorks
  可视化解决方案
    Gephi
    Keylines
    Linkurio.us
    Neo4j 浏览器
    Tom Sawyer 图可视化

查询例子
  推荐系统
    和自己购买了相同物品的人还买了什么?
      match (pl:Person)-[:BOUGHT]->(prodl:Product)<-[:BOUGHT]-(p2:Person)­[:BOUGHT]->(prod2:Product)
      where not (pl)-[:BOUGHT]->(prod2)
      return pl.name as FirstPerson, p2.name as SecondPerson, prodl.name as CommonProduct, prod2.name as RecommendedProduct;
    和自己购买了两件以上相同物品的人还买了什么?
      match (pl:Person)-[:BOUGHT]->(prodl:Product)<-[:BOUGHT]-(p2:Person)­[:BOUGHT]->(prod2:Product)
      with pl, p2, count(prodl) as NrOfSharedProducts, collect(prodl) as SharedProducts, prod2
      where not (pl)-[:BOUGHT]->(prod2) AND NrOfSharedProducts > 2
      return pl.name as FirstPerson, p2.name as SecondPerson, extract(x in SharedProducts | x.name) as SharedProducts, prod2 ame as RecommendedProduct; 
    自己购买了一件以上同一品牌的商品后,推荐同一品牌的其他商品
      MATCH (p:Person)-[:BOUGHT]->(prodl:Product)­[:MADE_BY]->(br:Brand)<-[:MADE_BY]-(prod2:Product)
      WITH p, br, prod2, count(prodl) as NrOfBrandProducts
      WHERE not (p)-[:BOUGHT]->(prod2) and NrOfBrandProducts > 1
      RETURN p.name as Person, br.name as Brand, collect(prod2.name) as RecommendedProducts
      ORDER BY Person ASC;
    找出购买过某个商品的用户,并寻找没有购买这些商品并可能从中受益的兄弟或姐妹(有相同的母亲或父亲〉
      match (p:Person)-[b:BOUGHT]->(prod:Product), p<-[rl]-(parent:Person)-[r2]->(sibling:Person)
      where type(rl) in [”MOTHER_OF”,”FATHER_OF”] and type(r2) in [”MOTHER_OF”,”FATHER_OF”]
      and not (sibling)-[:BOUGHT]->(prod)
      return p.name as Person, prod.name as RecommendedProduct, collect(sibling.ame) as ForSiblings;
    和自己购买了相同物品的兄妹还买了同一品牌的什么商品?
      match (pl:Person)-[:BOUGHT]->(prodl:Product)<-[:BOUGHT]-(p2:Person)-[:BOUGHT]->(prod2:Product),
            pl<-[rl]-(parent:Person)-[r2]->p2,
            prodl-[:MADE_BY]->(br:Brand)<-[:MADE_BY]-(prod2)
      where type(rl) in [”MOTHER_OF”,”FATHER_OF”] and type(r2) in [”MOTHER_OF”,”FATHER_OF”] and not (pl)-[:BOUGHT]->(prod2)
      return pl.name as FirstPerson, p2.name as SecondPerson, br.name as Brand, prod2.ηame as RecommendedProduct; 
  电影库联系
    查找四层以内最短路径
      match p=shortestpath((tom:Person{name:"Tom Hanks"})-[*1..4]-(other:Person{name:"Meg Ryan"}))
      return p;
    找到和Tom Hanks没有合作过的演员,但Tom Hanks的合作伙伴曾经与其合作过。找出这些合作伙伴可以介绍的人数。
      match (tom:Person{name:"Tom Hanks"})-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(other:Person)-[:ACTED_IN]->(m2:Movie)<-[:ACTED_IN]-(other2:Person)
      where not (other2)-[:ACTED_IN]->(m)
      return other.name as Recommended,count(distinct other2) as Strength
      order by Strength desc;

备份与恢复
  社区版
    只有冷备(脱机)是可行的。
      先停止服务,然后复制整个$NEO HOME data 目录到安全存储位置,再重启服务。
      恢复备份数据,先停止服务,用备份替换$NEO HOME data 目录,再重启服务。
    neo4j-amin dump --to=file --database=optionnalDBName
    neo4j-amin load from=file --database=optionnalDBName --force
  企业版
    可以在线备份
      需要打开配置项
        dbms.backup.enabled=true
        dbms.backup.address=0.0.0.0:6362
      neo4j-admin backup --backup-dir=<path>
                   [--verbose]
                   [--from=<host:port>]
                   [--database=<database>]
                   [--fallback-to-full=<true/false>]
                   [--pagecache=<size>]
                   [--check-consistency=<true/false>]
                   [--check-graph=<true/false>]
                   [--check-indexes=<true/false>]
                   [--check-label-scan-store=<true/false>]
                   [--check-property-owners=<true/false>]
                   [--report-dir=<path>]
                   [--additional-config=<path>]

      neo4j-admin restore --from=<path> [--verbose] [--database=<database>] [--force]
    恢复集群备份
      先关掉所有服务器实例
      在核心服务器上执行neo4j-admin unbind
      在所有实例执行neo4j-admin restore

程序开发
  JAVA嵌入式API
  使用驱动包开发
  HTTP API
  Spring-Data-Neo4j
  JDBC
  JCypher

Hibernate OGM neo4j
  数据类型
    自动匹配类型
      java.lang.Boolean;
        Optionally the annotations @Type(type = "true_false"), @Type(type = "yes_no") and @Type(type = "numeric_boolean") can be used to map boolean properties to the characters 'T'/'F', 'Y'/'N' or the int values 0/1, respectively.
      java.lang.Character
      java.lang.Byte
      java.lang.Short
      java.lang.Integer
      java.lang.Long
      java.lang.Float
      java.lang.Double
      java.lang.String
    下列JAVA类型会被转换成String
      java.math.BigDecimal
      java.math.BigInteger
      java.util.Calendar
        存储格式 "yyyy/MM/dd HH:mm:ss:SSS Z"
      java.util.Date
        存储格式 "yyyy/MM/dd HH:mm:ss:SSS Z"
      java.util.UUID
      java.util.URL
  下列注解会同时生成唯一约束
    @Id
    @EmbeddedId
    @NaturalId
    @Column( unique = true )
    @Table( uniqueConstraints = @UniqueConstraint(columnNames = { "column_name" } ) )

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值