FullText Search / IndexLookup using Neo4jClient - neo4jclient

I am trying to execute the following Cypher statement
"START b=node:customer_full_text_idx('ID:"ASHLAND"') return b
I am using this method
var results = _graphClient.QueryIndex<Customer>(Base.INDEX_CUSTOMER_FULL_TEXT, IndexFor.Node, "ID:" + "ASHLAND");
This method throws Lucene exceptions sometimes. This issue is documented at https://bitbucket.org/Readify/neo4jclient/issue/54/spaces-in-search-text-while-searching-for. The QueryIndex is deprecated and I tried recommended Syntax
I tried using recommend Cypher
var results = _graphClient
.Cypher
.Start(new { n = Node.ByIndexLookup(Base.INDEX_CUSTOMER_FULL_TEXT, "ID", "ASHLAND") })
.Return<Customer>("n")
.Results;
But above statement does not return any results. I think the problem is that above syntax is not designed for FullText and it inserts '=' in the Cypher start. Whereas it expects a ":" between ID and Name. Or may be I am missing something obvious.
Please share any examples using Neo4jClient using the .Start Query. TIA.

Use Node.ByIndexQuery instead of Node.ByIndexLookup.
(You were using a query before, then swapped to a lookup in the new syntax.)
This is a lookup: http://docs.neo4j.org/chunked/snapshot/query-start.html#start-node-by-index-lookup
This is a query: http://docs.neo4j.org/chunked/snapshot/query-start.html#start-node-by-index-query

Related

Unable to apply skip, limit and order clauses in Neo4j using rest cypher

I am using Neo4j 2.1.5 using dependency neo4j-rest-graphdb:2.0.1 in Grails and I query my DB using
RestAPI restapi = new RestAPIFacade("http://localhost:7474/db/data")
RestCypherQueryEngine rcqer=new RestCypherQueryEngine(restapi)
I created a parameter list
Map<String, String> paramVal = new HashMap<>(); paramVal.put('limit', 10); paramVal.put('skip', 0); paramVal.put('order', 'name');
My query looks like this
String query = "match (c:MyLabel) return id(c) as Id, c.name as name skip ${param}.skip limit ${param}.limit;
Execute the query like this
result = rcqer.query(query,org.neo4j.helpers.collection.MapUtil.map("param",paramVal))"
This shows error Invalid input '.': expected whitespace, Limit, LOAD CSV,.....
However works perfect when the parameters are used only in where clause.
Also the result is not in order while using only for order by clause, and works without any error.
Please let me know what is missing or if there is a limitation there.
Thanks in advance.
I don't use that particular part of the library but I would expect that you do not need to reference param directly as that is what the {} syntax is for (no dollar), this would make your query:
String query = "match (c:MyLabel) return id(c) as Id, c.name as name skip {skip} limit {limit}

Dynamically return from Neo4jclient

I know how to dynamically create my MATCH and WHERE clauses, and in my situation it's unfortunately something I've got to do... SO, I have something like (and this is a contrived example):
var query = client
.Cypher
.Match("(u1:User)-[:LINKED]->(w:Web)","(u2:User)-[:LINKED]->(w:Web)","(u3:User)-[:LINKED]->(w:Web)")
.Where("u1.User.Id = {u1Param}").WithParam("u1Param", 1)
.AndWhere("u2.User.Id = {u2Param}").WithParam("u2Param", 2)
.AndWhere("u3.User.Id = {u3Param}").WithParam("u3Param", 3);
The Match and Where are dynamically generated based on user input, and this generates the correct Cypher.
MATCH
(u1:User)-[:LINKED]->(w:Web), (u2:User)-[:LINKED]->(w:Web), (u3:User)-[:LINKED]->(w:Web)
WHERE
u1.User.Id = 1
AND u2.User.Id = 2
AND u3.User.Id = 3
On the server (in Cypher) I can do something like:
RETURN u1, u2, u3
and I'll get the 3 nodes I'm looking for. My problem is the general way of Returning data via the neo4jclient is via an Expression, so, to replicate I would do:
query.Return(
(u1, u2, u3) =>
{
U1 = u1.As<User>(),
U2 = u2.As<User>(),
U3 = u3.As<User>()
});
I don't know that there will only be '3' responses, there could be many more, or indeed less. Any ideas on how to achieve this? Either as is, or in a totally different way, I'm open to all options.
I'd like to something like:
query.Return<User>("u1", "u2", "u3"); //returning IEnumerable<User>
or maybe:
query.Return<User>("u1").AndReturn("u2").AndReturn("u3");
I know I can revert for these queries to calling the db directly through HttpClient or some such, but I'd rather avoid that if I can. To be honest I'd be happy with parsing them all to dynamic, but that's not possible at present (or is it??? :)).
Neo4jClient doesn't have any good solutions for dynamic return shapes like this.
In this contrived example at least, can you just flatten the nodes into a single list?
.Return<IEnumerable<User>>("[u1, u2, u3]")
You can easily tell which is which with the Id property that you're using in the WHERE clause but would also be available in C#.

Lambda expression in WHERE clause not working as expected

I'm new to Neo4j and trying to do a simple Cypher query using a lambda expression in the where clause but for some reason I can't seem to figure out why this isn't working.
Looks like:
class HealthNode {
public string Name{get;set;}
//Other Stuff
}
string Name = "Foobar";
var query = client
.Cypher
.Start(new { n = Neo4jClient.Cypher.All.Nodes })
.Where((HealthNode n) => n.Name == Name)
.Return<HealthNode>("n");
If I dump the Text and Parameters I'm getting:
START n=node(*)
WHERE (n.Name! = {p0})
RETURN n
//P0 Foobar
When I execute this, I of course get:
Cypher does not support != for inequality comparisons. Use <> instead
Why in the world is an extra Exclamation point to the name of the variable?
The ! means that the result will be false if the property doesn't exist. So, if you have more than one type in the graph, and that other type doesn't have a 'Name' property, neo4j won't bother matching.
See Neo4J Documentation for more info.
As to getting the != warning, are you changing the query at all when you paste it? Reformatting it? As I get the same warning if I do:
WHERE (n.Name != {p0})
but don't get any warning, and a successful completion if I use:
WHERE (n.Name! = {p0})
I think I found the cause of the problem here:
There was a change made to the 2.0 parser that implements NULL IF by default (instead of returning an error on a missing property) and removes the ! and ? operators since they no longer do anything.
neo4j pull request 1014
I suspect this will break a lot of things and not just Neo4J Client.
Fixed in Neo4jClient 1.0.0.625 and above, when talking to Neo2j 2.0.

Incorrect sort order with Neo4jClient Cypher query

I have the following Neo4jClient code
var queryItem = _graphClient
.Cypher
.Start(new
{
n = Node.ByIndexLookup("myindex", "Name", sku),
})
.Match("p = n-[r:Relationship]->ci")
.With("ci , r")
.Return((ci, r) => new
{
N = ci.Node<Item>(),
R = r.As<RelationshipInstance<Payload>>()
})
.Limit(5)
.Results
.OrderByDescending(u => u.R.Data.Frequency);
The query is executing fine but the results are not sorted correctly (i.e. in descending order). Here is the Payload class as well.
Please let me know if you see something wrong with my code. TIA.
You're doing the sorting after the .Results call. This means that you're doing it back in .NET, not on Neo4j. Neo4j is returning any 5 results, because the Cypher query doesn't contain a sort instruction.
Change the last three lines to:
.OrderByDescending("r.Frequency")
.Limit(5)
.Results;
As a general debugging tip, Neo4jClient does two things:
It helps you construct Cypher queries using the fluent interface.
It executes these queries for you. This is a fairly dumb process: we send the text to Neo4j, and it gives the objects back.
The execution is obviously working, so you need to work out why the queries are different.
Read the doco at http://hg.readify.net/neo4jclient/wiki/cypher (we write it for a reason)
Read the "Debugging" section on that page which tells you how to get the query text
Compare the query text with what you expected to be run
Resolve the difference (or report an issue at http://hg.readify.net/neo4jclient/issues/new if it's a library bug)

How do I use an index that has dots in the name?

I'm just starting to learn the Cypher query language and GraphDb in general. I've created some indexes using the class name of my nodes like:
"com.acme.node.SomeNodeType"
I can't for the life of me figure out how to reference this index in Cypher. I found this thread but using ` didn't work for me.
So I guess I have 2 questions:
Is it possible to use an index with dots in the name?
If so, how do I specify the name in the query?
can you try to query them with '' like
start n = node:`my.index`('name:test') return n
?

Resources