I generate a graph with the word of a sentence as tokens and dependency relations as edges.
This info comes from a external Tool in the format of ((word, index), (word, index), relation) tuple. Each word can have many dependencies and I want only one node per word.
When I process each dependency I want to search it by their ID, but when i Try to use find_vertex() i get the next Exception:
TypeError: No registered converter was able to extract a C++ reference to type graph_tool::GraphInterface from this Python object of type Graph
This is the code:
def graph(self, sentence, sentenceNamespace="sentence", separator="_"):
graph = Graph()
root_node = graph.add_vertex()
# Create a link to Root Node
graph.graph_properties['root'] = graph.new_graph_property("python::object", root_node)
# Create Node's properties
graph.vertex_properties['id'] = graph.new_vertex_property("string")
graph.vertex_properties['form'] = graph.new_vertex_property("string")
graph.vertex_properties['ord'] = graph.new_vertex_property("int64_t")
# Create edge's properties
graph.edge_properties['type'] = graph.new_edge_property("string")
# Create the root node
graph.vertex_properties['form'][root_node] = "S"
graph.vertex_properties['ord'][root_node] = -1
# Find or create the dependant and governor nodes and link with a new edge
for dependency in self.dependency(sentence):
dependency_governor = dependency[0]
# Governor's generated ID
governor_name = "{1}{0}{2[0]}{0}{1[1]}".format(separator, sentenceNamespace,dependency_governor )
dependency_dependant = dependency[1]
# Dependant's generated ID
dependant_name = "{1}{0}{2[0]}{0}{1[1]}".format(separator, sentenceNamespace, dependency_dependant)
# Relation Type
relation = dependency[2]
# This is the problematic Line ################################################
governor = find_vertex(graph, graph.vertex_properties['id'], governor_name)
##############################################################
# If search is successful use the first node else create a new one
if governor :
governor = governor[0]
else:
governor = graph.add_vertex()
graph.vertex_properties['id'][governor] = governor_name
graph.vertex_properties['form'][governor] = dependency_governor[0]
graph.vertex_properties['ord'][governor] = dependency_governor[1]
dependant = find_vertex(graph, 'id', dependant_name)
# If search is successful use the first node else create a new one
if dependant :
dependant = dependant[0]
else:
dependant = graph.add_vertex()
graph.vertex_properties['id'][dependant] = dependant_name
graph.vertex_properties['form'][dependant] = dependant_dependant[0]
graph.vertex_properties['ord'][dependant] = dependency_dependant[1]
# Link the nodes with the new dependency relation
dependency_edge = graph.add_edge(governor, dependant)
graph.edge_properties['type'][dependency_edge]= relation
return graph
This bug has been fixed in the git version.
Related
I have the following neo4j models with a Document and Text relationship, where multiple texts are linked to a document :
class Document(StructuredNode):
"""Document Neo4J model for documents"""
document_id = IntegerProperty(required = True)
class Text(StructuredNode):
"""Text model for managing texts"""
# Inherent text properties
text_id = IntegerProperty(required = True)
text = StringProperty(required = True)
document = RelationshipTo('Document', "PARENT")
In order to fetch ALL the Text objects linked with a specific document, I am using traversal as follows :
def get_all_texts_by_document_id(document_id):
document = Document.nodes.get_or_none(document_id = document_id)
definition = dict(node_class = Text, direction = EITHER, relation_type = "PARENT", model = None)
document_to_text_traversal = Traversal(document, Text.__label__, definition)
texts = document_to_text_traversal.all()
print(f"Returning {len(texts)} texts for document_id {document_id}")
return texts
I want to fetch a text with specific text ID and currently I am iterating with an if condition over the list of all the texts received using the above function.
Is there an inbuilt method / better way to filter on the basis of text_id once the traversal is done ?
I am not aware of any way to filter nodes after traversal with neomodel.
However, if you do not have to use Traversal objects, you could use something like this:
add the relationship from Text to Document by adding this line to your Document class:
texts = RelationshipFrom('Text', "PARENT")
Follow the PARENT relationship and filter on the end nodes:
document = Document.nodes.get_or_none(document_id=1)
if document:
texts = document.texts.filter(text_id=1)
print(texts.all())
I'm using the python API for Azure DevOps, I am trying to get a list of repo and branches each repo has. I don't know what members an object has when the API call returns the object. I am not sure if the documentation is complete, How to know what members an object has?
like for an object of "repo", I guessed the "name" property
from azure.devops.connection import Connection
from msrest.authentication import BasicAuthentication
import pprint
# Fill in with your personal access token and org URL
personal_access_token = 'YOURPAT'
organization_url = 'https://dev.azure.com/YOURORG'
project_name = "XYZ"
# Create a connection to the org
credentials = BasicAuthentication('', personal_access_token)
connection = Connection(base_url=organization_url, creds=credentials)
# Get a client (the "core" client provides access to projects, teams, etc)
git_client = connection.clients.get_git_client
# Get the first page of projects
get_repos_response = git_client.get_repositories(project_name)
index = 0
for repo in get_repos_response:
pprint.pprint(str(index) + "." + repo.name)
index += 1
In the above code, I just guessed the name property of a repo. I want to know what branches each of these repos have.
TIA
Based on these description, you want to apply the python api to get Repos list, branch list of corresponding repos and the creator of branch. For >>when the branch was last used, not sure whether it means the latest update time of the branch.
If this, just refer to this source code sample.
Get repositories:
It can only be got based on the project name provided, so use _send to pass the parameters to client:
route_values = {}
if project is not None:
route_values['project'] = self._serialize.url('project', project, 'str')
query_parameters = {}
if include_links is not None:
query_parameters['includeLinks'] = self._serialize.query('include_links', include_links, 'bool')
if include_all_urls is not None:
query_parameters['includeAllUrls'] = self._serialize.query('include_all_urls', include_all_urls, 'bool')
if include_hidden is not None:
query_parameters['includeHidden'] = self._serialize.query('include_hidden', include_hidden, 'bool')
response = self._send(http_method='GET',
location_id='225f7195-f9c7-4d14-ab28-a83f7ff77e1f',
version='6.0-preview.1',
route_values=route_values,
query_parameters=query_parameters)
return self._deserialize('[GitRepository]', self._unwrap_collection(response))
Get branches:
Add repository_id and base_version_descriptor additionally:
if project is not None:
route_values['project'] = self._serialize.url('project', project, 'str')
query_parameters = {}
if include_links is not None:
query_parameters['includeLinks'] = self._serialize.query('include_links', include_links, 'bool')
if include_all_urls is not None:
query_parameters['includeAllUrls'] = self._serialize.query('include_all_urls', include_all_urls, 'bool')
if include_hidden is not None:
query_parameters['includeHidden'] = self._serialize.query('include_hidden', include_hidden, 'bool')
branch creator and the latest update time, these message are contained in one specified branch and should be get by getting branch. At this time, the name is necessary which represent one specified branch name:
route_values = {}
if project is not None:
route_values['project'] = self._serialize.url('project', project, 'str')
if repository_id is not None:
route_values['repositoryId'] = self._serialize.url('repository_id', repository_id, 'str')
query_parameters = {}
if name is not None:
query_parameters['name'] = self._serialize.query('name', name, 'str')
if base_version_descriptor is not None:
if base_version_descriptor.version_type is not None:
query_parameters['baseVersionDescriptor.versionType'] = base_version_descriptor.version_type
if base_version_descriptor.version is not None:
query_parameters['baseVersionDescriptor.version'] = base_version_descriptor.version
if base_version_descriptor.version_options is not None:
query_parameters['baseVersionDescriptor.versionOptions'] = base_version_descriptor.version_options
When i created two node and their relation using transaction as shown below, i am able to use graph.match() to check if relation exist.
from py2neo import Graph, Node, Relationship, NodeSelector
g = Graph('http://localhost:7474/db/data', user='uname', password='pass')
tx = g.begin()
a = Node("Person", name="Alice")
tx.create(a)
b = Node("Person", name="Bob")
tx.create(b)
ab = Relationship(a, "KNOWS", b)
tx.create(ab)
tx.commit()
relations = g.match(start_node=a, rel_type="KNOWS", end_node=b)
list(relations) // this returns [(alice)-[:KNOWS]->(bob)]
Later i tried to pass start_node and end_node to graph.match() function as shown below, but it didn't work instead returned ERROR : Nodes for relationship match end points must be bound
d = Node("Person", name="Alice")
e = Node("Person", name="Bob")
relations = g.match(start_node=d, rel_type="KNOWS", end_node=e)
list(relations) // this returns error " Nodes for relationship match end points must be bound "
What is wrong with the above code to fetch an exixting relationship between Alice and Bob
The problem in following code
d = Node("Person", name="Alice")
e = Node("Person", name="Bob")
relations = g.match(start_node=d, rel_type="KNOWS", end_node=e)
list(relations) // this returns error " Nodes for relationship match end points must be bound "
is that Node is used to create new node as #InverseFalcon mentioned in the comment. it did not points to actual node in server. it worked to check relation at the time of creation ( First set of code in my question ) of nodes is because after creating the nodes the Node class return node object.
Following code worked for my project
d = g.run("MATCH (a:Person) WHERE a.name={b} RETURN a", b="Alice")
list_d = list(d)
start_node = list_d[0]['a']
e = g.run("MATCH (a:Person) WHERE a.name={b} RETURN a", b="Bob")
list_e = list(e)
end_node = list_e[0]['a']
relations = g.match(start_node=start_node, rel_type="KNOWS", end_node=end_node)
I have the following code:
import py2neo
from py2neo import Graph, Node, Relationship
def createRelationshipWithProperties():
print("Start - Creating Relationships")
# Authenticate the user using py2neo.authentication
# Ensure that you change the password 'sumit' as per your database configuration.
py2neo.authenticate("localhost:7474", "neo4j", "")
# Connect to Graph and get the instance of Graph
graph = Graph("http://localhost:7474/db/data/")
# Create Node with Properties
amy = Node("FEMALE", name="Amy")
# Create one more Node with Properties
kristine = Node("FEMALE",name="Kristine")
# Create one more Node with Properties
sheryl = Node("FEMALE",name="Sheryl")
kristine_amy = Relationship(kristine,"FRIEND",amy,since=2005)
print (kristine_amy)
amy_sheryl = Relationship(sheryl,("FRIEND"),amy,since=2001)
#Finally use graph Object and Create Nodes and Relationship
#When we create Relationship between, then Nodes are also created.
resultNodes = graph.create(kristine_amy)
resultNodes1 = graph.create(amy_sheryl)
#Print the results (relationships)
print("Relationship Created - ",resultNodes)
print("Relationship Created - ",resultNodes1)
if __name__ == '__main__':
createRelationshipWithProperties()
The resultsNodes = graph.create line seems to commit the nodes and relationships to the server because I can see them when I match(n) Return n. However, when the code prints resultsNodes, I get None as if they don't exist. This is the output that I get:
Start - Creating Relationships
(kristine)-[:FRIEND {since:2005}]->(amy)
Relationship Created - None
Relationship Created - None
You're using the API incorrectly. The create method doesn't return nodes but instead updates the supplied argument. Therefore to get the relationship nodes, you need to interrogate the relationship object after performing the create.
I'm using py2neo (version 1.6). I want to get an existing node by its property from the graph and then use it to create a relationship.
My solution:
graph = neo4j.GraphDatabaseService("http://...")
query = neo4j.CypherQuery(graph,"MATCH (n:NodeType) where n.property = 'property' return n")
r = query.execute()
if len(r.data)==0:
raise Exception("node does not exist")
node = r.data[0]['n']
newNode = batch.create(node(name="APropertyOfNewNode"))
batch.add_labels(newNode, "LableOfNewNode")
relation = rel(node, "relationshipName", newNode)
batch.create(relation)
batch.submit()
batch.clear()
Is there an high level way to get an existing node by its property without using CypherQuery and writing plain cypher?
You can use GraphDatabaseService.find:
from py2neo import neo4j
graph = neo4j.GraphDatabaseService('http://localhost:7474/db/data/')
movies = graph.find('Movie', 'title', 'The Matrix')
But graph.find returns a generator object.
movies
# <generator object find at 0x10b64acd0>
So you can only iterate through it once.
for movie in movies:
print type(movie)
print movie['tagline']
# <class 'py2neo.neo4j.Node'>
# Welcome to the Real World