Neo4j Import Tool ID Spaces in Cypher Query - import

I'm using the Neo4j Import Tool to import some nodes, and am trying to understand how ID spaces and labels work together and affect the behavior of cypher queries that match on nodes with specific IDs.
So for example, suppose I load nodes into two ID spaces ID_SPACE_X and ID_SPACE_Y:
x_nodes.csv:
id:ID(ID_SPACE_X),field1:string,field2:long,:LABEL
1,"foo",42,A
y_nodes.csv:
id:ID(ID_SPACE_Y),field1:string,:LABEL
1,"bar",A
Then I perform the following Cypher query:
MATCH (n:A {id:1}) RETURN n;
Which node is returned? Can you express the ID space in a cypher query in order to return the right node? Or must labels assigned to nodes in one ID space be exclusive to that ID space?
Thanks for any help.

ID spaces are only meaningful to the Import Tool. They enable the tool to correctly detect uniqueness errors.
They have no connection to node labels.
So, your example is buggy. You are telling the Import Tool that it is OK to create 2 A nodes with the same id property value. This will cause 2 such nodes to be created.

Related

How can I alias labels (using a query) in Grafana?

I'm using Grafana v9.3.2.2 on Azure Grafana
I have a line chart with labels of an ID. I also have an SQL table in which the IDs are mapped to simple strings. I want to alias the IDs in the label to the strings from the SQL
I am trying to look for a transformation to do the conversion.
There is a transformation called “rename by regex”, but that will require me to hardcode for each case. Is there something similar with which I don't have to hardcode for each case.
There is something similar for variables - https://grafana.com/blog/2019/07/17/ask-us-anything-how-to-alias-dashboard-variables-in-grafana-in-sql/. But I don't see anything for transformations.
Use 2 queries in the panel - one for data with IDs and seconds one for mapping ID to string. Then add transformation Outer join and use that field ID to join queries results into one result.
You may need to use also Organize fields transformation to rename, hide unwanted fields, so only right fields will be used in the label at the end.

Modifying queries on the fly depending on selected filters

In an existing codebase some tables are now horizontally sharded within the same database but in different namespaces.
E.g. let's say there previously was a large table users which is now sharded by the country field so there are now the following tables: us.users, ca.users, es.users etc.
Since every single query to the tables already contains the country filter I was thinking of the following minimalistic adjustment so that there's no need to subclass the original model for every country manually or dynamically:
class SessionWithShardedTableSupport(Session):
""" Use sharded tables on the fly """
def connection(self, mapper=None, clause=None, bind=None, close_with_result=None, **kw):
if mapper and mapper.local_table.name == 'users':
mapper.local_table.schema = '???' # `us` or `ca` or `es`
return super().connection(mapper, clause, bind, close_with_result, **kw)
The solution would work fine if there was a way to get the country filter from the query from within the session but there doesn't seem any (at least inspecting both mapper & clause parameters didn't reveal them).
1) Is there a way to get the where clause / the filters from within the session?
2) Is there maybe a better way to adjust the table name / table namespace on the fly with minimalistic changes to the existing code?

How to Query Jackrabbit for same name siblings

Is it possible to find the same-name siblings (SNS) using JCR-SQL2, JCR-SQL or QueryBuilder in Adobe CQ5/Adobe Experience Manager. I'm trying to match those nodes with a query having the following criteria without having to traverse the whole repository (slow and long running operation):
if(node.getIndex() > 1) {
// this node is matching the SNS criteria
}
SNS are defined as follows:
/a/b/c
/a/b/c[2]
/a/b/c[3]
/a/b[2]/c[2]
/a/b/c[3]
/a/d/f
/a/d/f[2]
So the result of the query should include /a/b/c[2], /a/b/c[3], /a/b[2]/c[2], /a/b/c[3], /a/d/f[2].
Adobe published a helpful article for this at:
https://helpx.adobe.com/experience-manager/kb/find-sns-nodes.html
EDIT: One query for this may be as below:
SELECT [jcr:path] FROM [nt:base] WHERE ISDESCENDANTNODE('/') AND [jcr:path] like '%\]'
The idea is that oak queries will be able to find indexed nodes that were migrated via SNS resolution logic. These names will contain ] in their names (paths for URI) which will be selectable via above query.
Use this query with caution as there are a lot of system nodes OOTB that have ] in the name and this is by design.
You can change [nt:base] to other relevant oak index for better filtering.
HTH

Cypher - WHERE and AND with 2 ids

I have a node with id 1 and a node with id 2 in the database and they are linked to each other. Why when I run this query
MATCH (a)-[r]-(b) WHERE id(a)=1 AND id(b)=2 RETURN *;
Nothing is returned?
Solution
I use GrapheneDB. Usually GrapheneDB presents the system node id on the node graphic but when you have an attribute id it presents that instead. When I ran the query I was using the graphic id which wasn't actually the system id so id(a) didn't give the expected result.
Because the WHERE clause is evaluated for each candidate result, and the entire clause must evaluate to true.
Also, putting MATCH (a)-[r]-(b) will only find parts of the graph where those two nodes are related.
If you just want to find nodes 1 and 2, you can do this:
MATCH n
WHERE id(n) = 1 OR id(n) = 2
RETURN n
However, you should not be using node ids. They are deprecated, and being phased out. There are lots of other ways to find and identify nodes that don't rely on their internal identifier. If you open a new question with your actual scenario, we could help you write a better query.

Retrieve first value with Xquery using a wildcard

In an XmlData column in SQL Server 2008 that has no schema assigned to it, how can I pull the first item at a particular node level? For example, I have:
SELECT
XmlData.value('//*/*[1]','NVARCHAR(6)')
FROM table
where XmlData.Exist('//*/*[1]') = 1
I assume this does not work because if there are multiple nodes with different names at the 2nd level, the first of each of those could be returned (and the value() requires that a singleton be selected.
Since I don't know what the names of any nodes will be, is there a way to always select whatever the first node is at the 2nd level?
I found the answer by chaining Xquery .query() and .value()
XMLDATA.query('//*/*[1]').value('.[1]','NVARCHAR(6)')
This returns the value of the first node and works perfectly for my needs.