سؤال

I'm a newbie to Django as well as neo4j. I'm using Django 1.4.5, neo4j 1.9.2 and neo4django 0.1.8

I've created NodeModel for a person node and indexed it on 'owner' and 'name' properties. Here is my models.py:

from neo4django.db import models as models2

class person_conns(models2.NodeModel):
     owner = models2.StringProperty(max_length=30,indexed=True)
     name = models2.StringProperty(max_length=30,indexed=True)
     gender = models2.StringProperty(max_length=1)
     parent = models2.Relationship('self',rel_type='parent_of',related_name='parents')
     child = models2.Relationship('self',rel_type='child_of',related_name='children')
     def __unicode__(self):
          return self.name

Before I connected to Neo4j server, I set auto indexing to True and and gave indexable keys in conf/neo4j.properties file as follows:

# Autoindexing

# Enable auto-indexing for nodes, default is false
node_auto_indexing=true

# The node property keys to be auto-indexed, if enabled
node_keys_indexable=owner,name

# Enable auto-indexing for relationships, default is false
relationship_auto_indexing=true

# The relationship property keys to be auto-indexed, if enabled
relationship_keys_indexable=child_of,parent_of

I followed Neo4j: Step by Step to create an automatic index to update above file and manually create node_auto_index on neo4j server.

Below are the indexes created on neo4j server after executing syndb of django on neo4j database and manually creating auto indexes:

  1. graph-person_conns lucene
    {"to_lower_case":"true", "_blueprints:type":"MANUAL","type":"fulltext"}
  2. node_auto_index lucene {"_blueprints:type":"MANUAL", "type":"exact"}

As suggested in https://github.com/scholrly/neo4django/issues/123 I used connection.cypher(queries) to query the neo4j database

For Example:

listpar = connection.cypher("START no=node(*) RETURN no.owner?, no.name?",raw=True)

Above returns the owner and name of all nodes correctly. But when I try to query on indexed properties instead of 'number' or '*', as in case of:

listpar = connection.cypher("START no=node:node_auto_index(name='s2') RETURN no.owner?, no.name?",raw=True)

Above gives 0 rows.

listpar = connection.cypher("START no=node:graph-person_conns(name='s2') RETURN no.owner?, no.name?",raw=True)

Above gives

Exception Value:
Error [400]: Bad Request. Bad request syntax or unsupported method. Invalid data sent: (' expected but-' found after graph

I tried other strings like name, person_conns instead of graph-person_conns but each time it gives error that the particular index does not exist. Am I doing a mistake while adding indexes?

My project mainly depends on filtering the nodes based on properties, so this part is really essential. Any pointers or suggestions would be appreciated. Thank you.

This is my first post on stackoverflow. So in case of any missing information or confusing statements please be patient. Thank you.

UPDATE: Thank you for the help. For the benefit of others I would like to give example of how to use cypher queries to traverse/find shortest path between two nodes.

from neo4django.db import connection

results = connection.cypher("START source=node:`graph-person_conns`(person_name='s2sp1'),dest=node:`graph-person_conns`(person_name='s2c1') MATCH p=ShortestPath(source-[*]->dest) RETURN extract(i in nodes(p) : i.person_name), extract(j in rels(p) : type(j))")

This is to find shortest path between nodes named s2sp1 and s2c1 on the graph. Cypher queries are really cool and help traverse nodes limiting the hops, types of relations etc.

Can someone comment on the performance of this method? Also please suggest if there are any other efficient methods to access Neo4j from Django. Thank You :)

هل كانت مفيدة؟

المحلول

Hm, why are you using Cypher? neo4django QuerySets work just fine for the above if you set the properties to indexed=True (or not, it'll just be slower for those).

 people = person_conns.objects.filter(name='n2')

The neo4django docs have some other querying examples, as do the Django docs. Neo4django executes those queries as Cypher on the backend- you really shouldn't need to drop down to writing the Cypher yourself unless you have a very particular traversal pattern or a performance issue.

Anyway, to more directly tackle your question- the last example you used needs backticks to escape the index name, like

listpar = connection.cypher("START no=node:`graph-person_conns`(name='s2') RETURN no.owner?, no.name?",raw=True)

The first example should work. One thought- did you flip the autoindexing on before or after saving the nodes you're searching for? If after, note that you'll have to manually reindex the nodes either using the Java API or by re-setting properties on the node, since it won't have been autoindexed.

HTH, and welcome to StackOverflow!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top