Cypher的数据结构: 属性类型, 复合类型和结构类型
属性类型
'Hello', "World"true, false, TRUE, FALSE结构类型
(a)-->()<--(b), 可以有向也可以无向注意在 cypher SQL 中, list 和标准 SQL 的区别, 不是用括号(), 而是用方括号[]. 有序的值的集合, ['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [ ]
['a', 'b'], [1, 2, 3]range(0, 10)表示从start到end的有序数字, Range函数包含两端[x IN range(0,10) WHERE x % 2 = 0 | x^3]无序Key/Value对的集合, n是节点, prop是节点的属性键, 引用属性的值的格式: n.prop
{ key: 'Value', listKey: [{ inner: 'Map1' }, { inner: 'Map2' }]}map_variable {map_element, [, …n]}.key, 用于引用Map对象中的属性key: <expression>表示嵌入到Map变量中的元素.*Map投影的示例, actor是Map变量, nrOfMovies是变量, 从Map变量中获取name属性, 并添加额外的属性nrOfMovies:
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)
WITH actor, count(movie) AS nrOfMovies
RETURN actor { .name, nrOfMovies }
create(
dis:Disease{
oid: "xxx1",
code: "111",
name: "2hh"
}
)
create也可以和return搭配, 直接返回结果, create也可以同时创建多个关系
create (m),(s)
比如已经有了两个节点, 我们想关联上关系
match(
a: Disease
), (
b: Disease
)
where a.code="111" and b.code="d1"
create (a)-[r:type]->(b)
return *
给这个线设置一些属性
match(
a: Disease{
code: '111'
}
), (
b: Disease{
code: 'd1'
}
)
create(a)-[r:relation{name : a.name + '--' + b.name}]->(b)
return type(r), r.name
假设不存在节点, 直接创建节点+关系了
create p=(reba:Person{name: 'reba'})-[:WORK_AT]->(nazha:Person{name:'nazha'})<-[:WORK_AT]-(jt:Person{name: 'jt'})
return p
对于节点比较少的可以使用
match (n) detach delete n
对于节点比较多的:
只能删除不带连接的节点
match(p:Person{name:'jt'}) delete p
-- or
match(p:Person{id:124}) delete p
用 detach 删除
match(p:Person{name: 'jt'}) detach delete p
match(p:Person{name: "reba"})-[r:WORK_AT]->() delete r
remove 删除节点和关系中的属性字段
-- 节点(或关系)的属性
{
"name": "诊断",
"code": "d1",
"oid": "xxx1"
}
-- 删除属性
match(d:Disease{name:"诊断"}) remove d.code
-- return 的 d.code 会变成 null
return d.name, d.oid, d.code
match(n {name: 'Andy'})
set n.surname = 'Taylor'
return n.name, n.surname
注意: 如果本身没有surname 这个属性, 会自动增加
还有一个高级写法, 用到了case when
match(n{name: 'Andy'})
set(
case
when n.age = 36
then n End
).wordIn = 'Malmo'
return n.name, n.wordIn
CASE
WHEN predicate THEN result
[WHEN ...]
[ELSE default]
END
使用等号赋值
match(n{name: 'Peter'})
set n.a1= '1' , n.a2 = '3'
return n
使用map赋值, 注意: 这样会清除所有原属性
MATCH (p { name: 'Peter' })
SET p = { name: 'Peter Smith', position: 'Entrepreneur' }
RETURN p.name, p.age, p.position
如果要保留原属性, 把=变成+=
match (p{name: 'Peter'})
SET p += { age: 38, hungry: TRUE , position: 'Entrepreneur' }
RETURN p.name, p.age, p.hungry, p.position
将这个属性置为null, 就是删除一个属性, 如下
MATCH (n { name: 'Andy' })
SET n.name = NULL RETURN n.name, n.age
使用一个空的map和等号, 这样即可删除节点所有属性
MATCH (p { name: 'Peter' })
SET p = { }
RETURN p.name, p.age
SET可用于将所有属性从一个节点或关系复制到另一个节点. 目标节点或关系的原属性会被清空.
MATCH (at { name: 'Andy' }),(pn { name: 'Peter' })
set at = pn
return at.name, at.age, at.hungry, pn.name, pn.age
MATCH (n { name: 'Stefan' })
SET n:German
RETURN n.name, labels(n) AS labels
match(n{name: 'Peter'})
set n:Swedish:Bossman
return n.name, labels(n) as labels
-- 标签为LABEL1的节点列表
match(d:LABEL1) return d
-- 标签同时为LABEL1和LABEL2的节点列表
match(d:LABEL1:LABEL2) return d
-- 类型为 RELATION1 的边列表
match(n)-[r:RELATION1]-(o) return r
-- 标签为LABEL1, 且 oid = '123' 的节点列表
match(d:LABEL1{oid: "123"}) return d
return 的作用是在match匹配上了以后, 选择哪些返回, 如果能确定返回的属性, 尽量不要全部返回
需要什么就返回什么, *表示返回所有的. 比如
MATCH p =(a { name: 'A' })-[r]->(b)
RETURN *
返回的结果就是满足上面p, a r, b关系的所有的可能结果
MATCH (a { name: 'A' })
RETURN a.age AS SomethingTotallyDifferent
对于没有属性的会返回一个null, 比如
MATCH (n)
RETURN n.age
如果返回的两个结果, 一个由age这个属性, 一个没有, 那么有的正常返回, 没有的返回null.
还可以在返回中包含运算, 并且返回的是多个元素也支持
MATCH (a { name: 'A' })
RETURN a.age > 30, "I'm a literal",(a)-->()
DISTINCT
MATCH (a { name: 'A' })-->(b)
RETURN DISTINCT b
这个和match差不多, 区别在于当没有查到东西的时候, 会返回一个null
比如下面的结果有值
match(p:Person{
name: 'reba'
})
optional match (p) -->(x)
return x
但是如果把方向换一下, 结果会变成两个null
match(p:Person{
name: 'reba'
})
optional match (p) <--(x)
return x
如果把optional去掉, 结果是 no records
使用WHERE指定复杂的查询条件
MATCH (n)
WHERE n.name = 'Peter' XOR (n.age < 30 AND n.name = 'Timothy') OR NOT (n.name = 'Timothy' OR n.name = 'Peter')
RETURN n.name, n.age
在WHERE中对id进行过滤, 返回标签为 LABEL1, 元素ID为 1, 2, 3 的元素
MATCH (n:LABEL1) WHERE id(n) IN [1,2,3] RETURN n
在WHERE中对label进行过滤
MATCH (n) WHERE n:Swedish RETURN n.name, n.age
不固定属性的过滤
with 'AGE' as propname
match (n)
where n[toLower(propname)] < 30
return n.name, n.age
属性存在性校验
MATCH (n)
WHERE exists(n.belt)
RETURN n.name, n.belt
以xx字符串开头
MATCH (n)
WHERE n.name STARTS WITH 'Pet'
RETURN n.name, n.age
以xx字符串结尾
MATCH (n)
WHERE n.name ENDS WITH 'ter'
RETURN n.name, n.age
字符串包含
MATCH (n)
WHERE n.name CONTAINS 'ete'
RETURN n.name, n.age
NOT 的使用
MATCH (n)
WHERE NOT n.name ENDS WITH 'y'
RETURN n.name, n.age
正则表达式的使用
MATCH (n)
WHERE n.name =~ 'Tim.*'
RETURN n.name, n.age
不区分大小写
MATCH (n)
WHERE n.name =~ '(?i)AND.*'
RETURN n.name, n.age
根据null过滤
MATCH (person)
WHERE person.name = 'Peter' AND person.belt IS NULL RETURN person.name, person.age, person.belt
首先记住, 不能根据关系或者节点进行排序, 只能根据属性
MATCH (n)
RETURN n.name, n.age
ORDER BY n.age, n.name
一般order by都是放在return后面
从头开始跳过几个数据, 一般在Order by 的后面, 如果没有order by 就放在return后面
MATCH (n)
RETURN n.name
ORDER BY n.name
SKIP toInteger(3*rand()) + 1
limit 一般是在最后了, 控制展示的个数
MATCH (n)
RETURN n.name
ORDER BY n.name
LIMIT toInteger(3 * rand())+ 1
这个关键字基本上是把create和match合并到一起
merge (robert:Critic{name: '111'})
return robert, labels(robert)
如果不存在这个节点, 会直接创建, 执行后再执行一遍, 作用只是相当于match了.
当然也可以从已经存在的节点中获取值, 比如
MATCH (person:Person)
MERGE (city:City { name: person.bornIn })
RETURN person.name, person.bornIn, city
从已经存在的节点中, 获取一些属性值, 然后进行复制. 当然, 这个操作可以是批量的
这个实际上是一个限定条件, 表达的是当创建的时候, 才执行, 不创建就不执行, 比如:
merge (c:Critic{name:'1112'})
on create set c.create = timestamp()
return c.name, c.create
这个语句中, 如果数据库中已经存在了一个1112那么就不会set值, 同样, 如果不存在, 那么就会执行set后面的部分.
这个命令和上述表达差不多, 不同的是它是匹配上了就进行set
MERGE (person:Person)
ON MATCH SET person.found = TRUE RETURN person.name, person.found
当然也可以同时设置多个属性值:
MERGE (person:Person)
ON MATCH SET person.found = TRUE , person.lastAccessed = timestamp()
RETURN person.name, person.found, person.lastAccessed
MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
ON MATCH SET keanu.lastSeen = timestamp()
RETURN keanu.name, keanu.created, keanu.lastSeen
现在数据库中是没有这个节点的, 也就是说会进行创建
MERGE 同样也能被用来match或者create关系.
比如已经存在两个节点, 想给他们MERGE一下关系
MATCH (charlie:Person { name: 'Charlie Sheen' }),(wallStreet:Movie { title: 'Wall Street' })
MERGE (charlie)-[r:ACTED_IN]->(wallStreet)
RETURN charlie.name, type(r), wallStreet.title
一下子处理多个关系, 比如:
MATCH (oliver:Person { name: 'Oliver Stone' }),(reiner:Person { name: 'Rob Reiner' })
MERGE (oliver)-[:DIRECTED]->(movie:Movie)<-[:ACTED_IN]-(reiner)
RETURN movie
创建一个无向的连接:
MATCH (charlie:Person { name: 'Charlie Sheen' }),(oliver:Person { name: 'Oliver Stone' })
MERGE (charlie)-[r:KNOWS]-(oliver)
RETURN r
有一些批量操作的写法, 能够帮助我们快速创建大量节点和关系, 比如:
MATCH (person:Person)
MERGE (city:City { name: person.bornIn })
MERGE (person)-[r:BORN_IN]->(city)
RETURN person.name, person.bornIn, city
将所有Person中出生地和实际的城市直接挂钩
上面这句话, 我们还可以改写下:
MATCH (person:Person)
MERGE (person)-[r:BORN_IN]->(city:City { name: person.bornIn })
RETURN person.name, person.bornIn, city
With关键字是连接多个查询的结果, 即将上一个查询的结果用作下一个查询的开始
我们用这样一段话, 来查询David连接过去的节点, 它向外连接关系大于1的那个节点
match(David{name: 'David'}) --(otherPerson)-->()
with otherPerson, count(*) as cnt
where cnt > 1
return otherPerson.name
match(Anders{name: 'Anders'}) --(otherPerson)-->()
with otherPerson, count(*) as cnt
where cnt > 1
return otherPerson.name
match(n)
with n
where n.name = 'David' or n.name = 'Bossman'
return collect(n.name)
MATCH (n { name: 'Anders' })--(m)
WITH m
ORDER BY m.name DESC LIMIT 1
MATCH (m)--(o)
RETURN o.name
我们先看这样一句话, 初步了解下unwind 的用法:
unwind [1, 2, 3, NULL] as x
return x, 'val' as y
with [1, 1, 2, 2] as coll
unwind coll as x
with distinct x
return collect(x) as setOfVals
其实是在合并列表
with [1, 2] as a, [3, 4] as b
unwind (a + b) as x
return x
with [[1, 2], [3, 4], 5] as nested
unwind nested as x
unwind x as y
return x, y
这是一个用法, 只要unwind的是一个[], 那么不管一起返回的是什么, 都会返回一个0rows.
unwind [] as empty
return empty, 'literal_that_is_not_returned'
unwind可以被用来检测是不是一个list
unwind null as x
return x, 'some_itearl'
如果直接unwind一个数字, 会报错:
unwind 5 as x
return x, '11'
批量的进行修改属性
match p=(begin)-[*]->(END)
where begin.name = 'A' And END.name = 'D'
foreach(n in nodes(p)| set n.marked = TRUE)
使用CALL可以调用一些函数, 比如来个最简单的调用一个库函数
CALL `db`.`labels`
这样子可以把所有类名全部列出来
union 就是把两个结果合并起来.
MATCH (n:Actor)
RETURN n.name AS name
UNION ALL
MATCH (n:Movie)
RETURN n.title AS name
如果不用union all 直接用union, 会对结果排除重复
MATCH (n:Actor)
RETURN n.name AS name
UNION
MATCH (n:Movie)
RETURN n.title AS name
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_