Python LanguageNeo4j и Cypher используют Py2Neo

Импорт и аутентификация

from py2neo import authenticate, Graph, Node, Relationship
authenticate("localhost:7474", "neo4j", "<pass>")
graph = Graph()

Вы должны убедиться, что ваша база данных Neo4j существует на localhost: 7474 с соответствующими учетными данными.

объект graph - это ваш интерфейс к экземпляру neo4j в остальной части вашего кода на Python. Скорее спасибо, что это глобальная переменная, вы должны сохранить ее в методе __init__ класса.

Добавление узлов в Neo4j Graph

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. Не забывайте этот шаг.

Добавление отношений к графику 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 важно для избежания дубликатов. Но в остальном это довольно простая операция. Имя отношения также важно, так как вы использовали бы его в расширенных случаях.

Запрос 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 для получения всех узлов с name свойства, которое начинается с text аргумента.

Запрос 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

Вы можете использовать этот запрос, чтобы найти все новостные статьи (n) связанные с местоположением (l) с помощью отношения.

Образцы запросов Cypher

Подсчитайте статьи, связанные с определенным человеком со временем

MATCH (n)-[]->(l) 
where l.name='Donald Trump'
RETURN n.date,count(*) order by n.date

Поиск других людей / мест, связанных с такими же новостными статьями, как Trump с не менее чем 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