1: 向Neo4j图中添加节点
results = News.objects.todays_news()
for r in results:
article = graph.merge_one("NewsArticle", "news_id", r)
article.properties["title"] = results[r]['news_title']
article.properties["timestamp"] = results[r]['news_timestamp']
article.push()
[...]
向图中添加节点非常简单,graph.merge_one非常重要,因为它可以防止重复项。(如果你运行脚本两次,那么第二次它会更新标题,而不会为相同的文章创建新节点)
timestamp应该是一个整数,而不是日期字符串,因为Neo4j没有真正的日期数据类型。如果将日期存储为'05-06-1989'这样的字符串,会导致排序问题。
article.push()是实际将操作提交到Neo4j的调用。不要忘记这一步。
2: 导入和身份验证
from py2neo import authenticate, Graph, Node, Relationship
authenticate("localhost:7474", "neo4j", "")
graph = Graph()
你必须确保你的Neo4j数据库存在于localhost:7474,并且具有适当的凭据。
graph对象是你在其余Python代码中与Neo4j实例交互的接口。与其将它作为一个全局变量,不如将其保留在类的__init__方法中。
3: 向Neo4j图中添加关系
results = News.objects.todays_news()
for r in results:
article = graph.merge_one("NewsArticle", "news_id", r)
if 'LOCATION' in results[r].keys():
for loc in results[r]['LOCATION']:
loc = graph.merge_one("Location", "name", loc)
try:
rel = graph.create_unique(Relationship(article, "about_place", loc))
except Exception, e:
print e
create_unique对于避免重复项很重要。除此之外,它是一个相当直接的操作。关系名称也很重要,因为在高级情况下你会用到它。
4: 查询1:新闻标题自动补全
def get_autocomplete(text):
query = """
start n = node(*) where n.name =~ '(?i)%s.*' return n.name,labels(n) limit 10;
"""
query = query % (text)
obj = []
for res in graph.cypher.execute(query):
# print res[0],res[1]
obj.append({'name':res[0],'entity_type':res[1]})
return res
这是一个示例Cypher查询,用于获取所有具有以参数text开头的属性name的节点。
5: 查询2:按特定日期和地点获取新闻文章
def search_news_by_entity(location,timestamp):
query = """
MATCH (n)-[]->(l)
where l.name='%s' and n.timestamp='%s'
RETURN n.news_id limit 10
"""
query = query % (location,timestamp)
news_ids = []
for res in graph.cypher.execute(query):
news_ids.append(str(res[0]))
return news_ids
你可以使用这个查询来查找所有通过关系连接到特定地点(l)的新闻文章(n)。
6: Cypher查询示例
按时间统计与特定人物相关的文章数量
MATCH (n)-[]->(l)
where l.name='Donald Trump'
RETURN n.date,count(*) order by n.date
搜索与特朗普相关的其他人物/地点(至少有5个关系节点)
MATCH (n:NewsArticle)-[]->(l)
where l.name='Donald Trump'
MATCH (n:NewsArticle)-[]->(m)
with m,count(n) as num where num>5:
return labels(m)[0],(m.name), num order by num desc limit 10