py2neo - updating existing node with new properties w/uniqueness constraint (merge_one) - neo4j

I've been trying to figure out a way to adapt the merge_one functionality from py2neo v2 to v3. I read in a Google group that "The merge_one method no longer exists in v3 as you should be able to use merge in all cases instead." but I can't figure out how to easily use regular merge in v3.
I'm trying to recreate Nicole White's neo4j twitter example project with a small modification. She used merge_one. There are uniqueness constraints on (u:User) - u.username and (t:Tweet) - t.id. Her script always has the same properties for Tweet and User nodes, but I am making a case where sometimes I want to go back and add more properties to an existing node with merge. However I get the error
py2neo.database.status.ConstraintError: Node 178 already exists with label Tweet and property "id"=[***]
I understand this is because when I have for example a Tweet that already exists with just an id and then I try to do
tw_dict = {'id'=t['id'], 'text':t['text'], 'created':t['created_at'],
'rts':t['retweet_count'],
'favs':t['favorite_count'], 'lang':t['lang']}
tweet = Node("Tweet", **tw_dict)
graph.create(tweet)
merge is not finding the same tweet with all those properties and when it tries to create one is running into the uniqueness constraint on Tweet's id. It looks like the merge_one function would have solved this, but it's not available in v3. So instead I've implemented the following:
exists = graph.find_one("Tweet", "id", t['id'])
if exists:
exists['text'] = t['text']
exists['created'] = t['created_at']
exists['rts'] = t['retweet_count']
exists['favs'] = t['favorite_count']
exists['lang'] = t['lang']
else:
tw_dict = {'text':t['text'], 'created':t['created_at'],
'rts':t['retweet_count'],
'favs':t['favorite_count'], 'lang':t['lang']}
tweet = Node("Tweet", **tw_dict)
graph.create(tweet)
but this seems repetitive to me. Is there not an easier way in py2neo to do something like updating an existing node with new properties and still specifying a property with a unique constraint (in this case id)? I think in Cypher I would do a merge on just the id and then set on match or set on create but I don't see how to do that with py2neo. I also tried to find in the documentation something that would allow an update of properties from a dictionary with an existing node but can't.

py2neo v3 now has graph.merge(), which you can use to the same effect.
First find or create the node with graph.merge(), matching only on its unique property, then update its other non-unique properties with node.push(). You would've had to do the same thing with graph.merge_one(), just with a slightly different syntax.
from py2neo import Graph, Node
graph = Graph()
tweet = Node('Tweet', id=123)
graph.merge(tweet)
tweet['text'] = 'Hello World'
tweet.push()
I should update that twitter script to use py2neo v3; thanks for the reminder.

Two things;
1.)
tweet.push() has been deprecated. The docs suggest using graph.push(tweet).
2.)
I am having trouble to get this working with a transaction such as:
transaction = graph.begin()
transaction.merge(tweet)
transaction.graph.push(tweet)
transaction.commit()
Any suggestion on the difference between using graph.merge and transaction.merge?

To update for py2neo v5 - 2020, you may update multiple properties for an existing node from a dictionary.
from py2neo import NodeMatcher
tw_dict = {'text':t['text'],
'created':t['created_at'],
'rts':t['retweet_count'],
'favs':t['favorite_count'],
'lang':t['lang']}
tweet = matcher.match('Tweet', id=123).first()
if tweet:
tweet.update(**properties)
graph.push(tweet)

Related

Get list of Measurements with Influx 2

I'm having trouble understanding how to use some InfluxDB 2 APIs from Python, using the influxdb-client-python library for InfluxDB 2
For example I would like to get a list of measurements in a bucket.
Official documentation (not Python) suggest this:
Use the schema.measurements() function to list measurements in a bucket.
import "influxdata/influxdb/schema"
schema.measurements(bucket: "example-bucket")
I have searched through the library's code to see if I could find something that does this. I might be wrong, but it appears that as of right now there's no interface for this functionality.
However, it is possible to do what you want by executing the following:
from influxdb_client import InfluxDBClient
address = "myaddress"
token = "mytoken"
org = "myorg"
client = InfluxDBClient(url=address, token=token, org=org)
qapi = client.query_api()
q = 'import "influxdata/influxdb/schema"\n\nschema.measurements(bucket: "example-bucket")'
tables = qapi.query(q)
for table in tables:
print(table)
for record in table.records:
print(record.values)
You will have to substitute any defined variables from this code sample with your own. Also, make sure that the bucket name in the query matches the bucket you want to query.
Finally, the token you use must have enough permissions to accomplish the task.

merge nodes based on common property and add all properties to the initial node

In this image you can see all the properties from a node, what I want to achieve is to merge the nodes based on CUI (id) and add those properties to one initial node.
I tried
START first=node(*), second=node(*)
WHERE exists (first.id) and exists (second.id)
WITH first, second
SKIP 20000 LIMIT 20000
WHERE first.id= second.id
SET first=second;
but there are no changes
then I tried calling the APOC
match (f:Disease),(b:Disease) where f.id=b.id
CALL apoc.refactor.mergeNodes([f,b]) yield node
return "none";
which gives me an error
ServiceUnavailable: WebSocket connection failure. Due to security
constraints in your web browser, the reason for the failure is not
available to this Neo4j Driver. Please use your browsers development
console to determine the root cause of the failure. Common reasons
include the database being unavailable, using the wrong connection URL
or temporary network problems. If you have enabled encryption, ensure
your browser is configured to trust the certificate Neo4j is
configured to use. WebSocket readyState is: 3
Can someone help with a query which merges the nodes and adds the properties so I will not lose information?
First, run this to create uniqueness constraint and add an index on id property of Disease. [IMPORTANT]
CREATE CONSTRAINT ON (d:Disease) ASSERT d.id IS UNIQUE
Then Run the following query to load the data.
This will create the node if it's not present and set the properties.
If the node already exists it will append the values.
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM 'file:///ConditionConcepts.csv' AS line FIELDTERMINATOR '\t'
MERGE (disease:Disease {id: line.CUI})
ON CREATE SET
disease.name_doctor = line.name,
disease.relevance = line.cui_relevance,
disease.trials = line.trials_count,
disease.search = line.search_frequency,
disease.select = line.select_frequency
ON MATCH SET
disease.name_doctor = disease.name_doctor+", "+line.name,
disease.relevance = disease.relevance+", "+line.cui_relevance,
disease.trials = disease.trials+", "+line.trials_count,
disease.search = disease.search+", "+line.search_frequency,
disease.select = disease.select+", "+line.select_frequency
I can show you an easier example of what I want
after I apply the following query
MATCH (o:Disease),(b:Disease)
WHERE o.id=b.id and o<>b and o.name_doctor<>b.name_doctor
SET o.name_doctor=o.name_doctor+", "+b.name_doctor
RETURN o,b;
I will have this result
but this is not what I want, in the end, I need to have one node which will have the properties of the others, something like this .
maybe there is a way of doing this at creation, I have to load a CSV file in order to have the data, if I use merge (instead of creating) or constraint, I will lose properties.
I need to find a way to create the nodes without losing any data.

Via Code - Change the order of Umbraco Nodes in Back office

During the Gathering Node data event, I want to run some code and based on the result I want to change the order of nodes in the Umbraco back office.
Is this possible? I'm using V6
In code there is a sort order method against Document
Document doc = new Document(<nodeId>);
doc.SortOrder = <int>;
This manipulates the database tables including cmsContentXml & UmbracoNode:

Creating relationships in neo4j

I have done a lot of reading by I can't seem to find the answer on this. If there's a duplicate post somewhere please point me to it!
Anyways, here it goes.
I'm trying to import data into Neo4J and create the relationships in order to easily graph the data. I was able to import the data without a problem using the LOAD CSV WITH HEADERS command now I'm not sure how to create the relationship piece.
My CSV/Table looks like this
source target action
172.x.x.x 172.y.y.y accept
172.x.x.x 172.y.y.y drop
All the data ends up in the same database and "table"
My goal is to have the following relationship scheme:
"Source"-------[action]------->"Target"
My first attempt was:
START n=node(*)
WHERE HAS(n.source) AND HAS(n.destination)
CREATE (n)-[:CONNECTS_TO]->(n)
I could not see the relationship at all after running this even though the browser shell said that it did create them and besides this does not take care of the "action" piece.
Any help would be appreciated.
You can load CSV into Neo4j by using following command
load csv with headers from "file:///file_path" as input
match (from:Node {source: input .source}),(to:Node {target:input.target})
create (from)-[:RELATION {type: input.action }]->(to)
*Note: You have to mention your lable name in the above query by replacing "Node".

In the Jira Python API, how can I get a list of all labels used in a project?

I am using the python API for Jira. I would like to get a list of all the labels that are being used in a project. I know that issue.fields.labels will get me just the labels of an issue, but I am interested in looping through all the labels used in a project. Found this to list all components in a project
components = jira.project_components(projectID)
Am looking for something similar, but for labels...
Using jira-python library for python3
For a whole project, you would write a loop to iterate through the issues in the project, then append the labels to a list.
from jira import JIRA
host = "http://<site>.atlassian.net"
jira = JIRA(host,basic_auth=(<user>, <password>))
projectlist = jira.search_issues('project = "Project Name"')
alllabels = []
for ticket in projectlist:
issue = jira.issue(ticket)
labels = issue.fields.labels
for i in labels:
alllabels.append(i)
If you wanted unique labels only you could use a set instead of a list for alllables.
Labels are a field that is shared across all issues potentially, but I don't think there is a REST API to get the list of all labels. So you'd either have to write a JIRA add-on to provide such a resource, or retrieve all the issues in question and iterate over them. You can simplify things by excluding issues that have no label
JQL: project = MYPROJ and labels is not empty
And restrict the fields that are returned from the search using the "fields" parameter for search_issues

Resources