Neo4j LIMIT if parameter is set - neo4j

is there a way to set a LIMIT only, if the parameter {limit} has an numeric value.
...
RETURN whatever
LIMIT {limit}
maybe in a way like this (i know, that the next code example does not work)
...
RETURN whatever
if({limit}>0)
LIMIT {limit}
thanks!

You should process this logic in your application layer by building dynamic queries.
Edit :
This can simply be done like the example below (in php but possible in all languages)
public function doMatchQuery($limit = null)
{
$query = 'MATCH (n) RETURN n';
if ($limit && $limit !== 0) {
// extend the query string
$query .= ' LIMIT '.$limit;
}
}
// Calling your function
$matchAll = $this->doMatchQuery(); // Return all n elements from the db
$matchFirstTen = $this->doMatchQuery(10); // Return the n elements with a limit of 10

Related

VSTS - VS402337: The number of work items returned exceeds the size limit of 20000. Change the query to return fewer items

In VSTS, I get this when there are more than 20k work items returned by a wiql query. I wanted to know if there is a parameter to limit the number of work items returned(even though the actual query may return 20000+ work items)?
Caused by: com.microsoft.tfs.core.ws.runtime.exceptions.SOAPFault:
VS402337: The number of work items returned exceeds the size limit of
20000. Change the query to return fewer items.
In this case, Andy gave two methods to fix this issue, you can refer to it.
1.Add the Query conditions to return fewer items just as the error message mentioned.
For example: SELECT * FROM WorkItems WHERE [System.TeamProject] = #project AND [System.State] = ‘Active' AND [System.AssignedTo] = ‘joselugo'
2.Split into groups to return them separately.
// There is a VSO limit of a query returning 20,000 results. Split into groups of 10,000 items maximum.
var results = new List<WorkItemReference>();
var counter = 10000;
var moreResults = true;
while (moreResults)
{
List<WorkItemReference> currentResults = this.WitClient.QueryByWiqlAsync(new Wiql
{
Query = $"SELECT System.ID FROM WorkItems WHERE System.TeamProject = '{Project}' AND {customQuery} AND System.ID >= {counter - 10000} AND System.ID < {counter}"}).Result.WorkItems.ToList();
if (currentResults.Count == 0)
{
// Verify there are no more items
try
{
results.AddRange(this.WitClient.QueryByWiqlAsync(new Wiql
{
Query = $"SELECT System.ID FROM WorkItems WHERE System.TeamProject = '{Project}' AND {customQuery} AND System.ID >= {counter}"
}).Result.WorkItems.ToList());
moreResults = false;
}
catch (Exception e)
{
if (e.ToString().Contains("VS402337"))
{
// There are still more results, so increment and try again.
}
else
{
throw;
}
}
}
else
{
results.AddRange(currentResults);
}
counter += 10000;
}
This workaround is for .net tfs sdk, I think you are using java tfs sdk, you can refer to the above code logic to modify.
When using the Wiql API, if you specify a value for $top it will limit it to the maximum results to return.

How to do mathematical computation in stored procedure in snowflake?

I am getting a count(*) after joining two Snowflake tables. This is done inside a stored procedure. If the count is greater than zero, I need to pass a value. My stored procedure gets called from a NiFi Processor and I have to return the value to NiFi so that an email can be sent from NiFi.
I am getting 'NaN' as output for the below code.
CREATE OR REPLACE PROCEDURE test_Delete_excep()
returns float not null
language javascript
as
$$
var rs;
var return_value = 0;
var SQL_JOIN = "select count(*) from (Select GT.VARIANTDATA from GOV_TEST GT inner join GOV_TEST_H GTH on GT.VARIANTDATA:COL1::String = GTH.VARIANTDATA:COL1::String where to_char(GT.VARIANTDATA) != to_char(GTH.VARIANTDATA));";
var stmt = snowflake.createStatement({sqlText: SQL_JOIN});
rs = stmt.execute();
rs.next();
return_value += JSON.stringify(rs.getColumnValue(1));
if (return_value > 0) { return 'email required';}
$$;
Here is the result:
Row TEST_DELETE_EXCEP
1 NaN
How can I do the arithmetic calculation and return a value to NiFi processor?
You are never returning a float value, which the SP defines as the return type. If return_value is greater than 0, it will try to return the string 'email required.', which is not a float. That will generate a NaN. If return_value is not greater than 0, the code will never return a value of any kind. That will return NULL. Since you specify NOT NULL for the return, that will force it to NaN
Also, I'm not sure why you're trying to stringify the rs.getColumnValue(1). The select count(*) will produce an integer value, which you can read directly.
You probably want something like this:
CREATE OR REPLACE PROCEDURE test_Delete_excep()
returns float not null
language javascript
as
$$
var rs;
var return_value = 0;
var SQL_JOIN = "select count(*) from (Select GT.VARIANTDATA from GOV_TEST GT inner join GOV_TEST_H GTH on GT.VARIANTDATA:COL1::String = GTH.VARIANTDATA:COL1::String where to_char(GT.VARIANTDATA) != to_char(GTH.VARIANTDATA));";
var stmt = snowflake.createStatement({sqlText: SQL_JOIN});
rs = stmt.execute();
if(rs.next()) {
return_value = rs.getColumnValue(1);
} else {
return -1;
}
return return_value;
$$;
This will return the row count produced by your join SQL. If you want something different, please clarify the desired output.

apoc.periodic.commit doesn't result in updates

The following query results in 10 updated nodes:
MATCH (a:ns3__Organization)-[r:ns4__isDomiciledIn]->(b:Resource)
WITH a,b LIMIT 10
SET a.isDomiciledIn = b.Country
I'm trying to apply it to my whole graph with apoc.periodic.commit through the following query:
CALL apoc.periodic.commit("
MATCH (a:ns3__Organization)-[r:ns4__isDomiciledIn]->(b:Resource)
WITH a,b LIMIT $limit
SET a.isDomiciledIn = b.Country
", { limit : 50000});
Somehow it results in 0 update. What am I doing wrong?
Thanks for your help.
You should try this one :
CALL apoc.periodic.commit("
MATCH (a:ns3__Organization)-[r:ns4__isDomiciledIn]->(b:Resource)
WHERE NOT a.isDomiciledIn = b.Country
WITH a,b LIMIT $limit
SET a.isDomiciledIn = b.Country
RETURN count(*)
", { limit : 50000});
You errors :
no count(*) at the end of your query. SO your query never ends
no WHERE clause to filter the result to only nodes that are not yet updated

Longest path based on relationship property

I need to find the longest path in Neo4j graph based on order of specific property of the relationship.
Imagine that the relationship has property date of integer type like that
[:Like {date:20140812}]
Consider the path:
A-[r1:Like]->B-[r2:Like]->C
This is valid path only if r1.date < r2.date
The question is how to find the longest path with Cypher.
You can do something like this but it won't be very efficient in cypher.
I would still limit the max-path-length to prevent it from exploding.
I'd probably use the Java API to achieve something like that.
You can try to run it with the new query planner in Neo4j 2.1 with the cypher 2.1.experimental prefix.
MATCH (a:Label {prop:value})
MATCH path = (a)-[r:Like*10]->(b)
WHERE ALL(idx in range(1,length(path)-1) WHERE r[idx-1].date < r[idx].date)
RETURN path, length(path) as len
ORDER BY len DESC
LIMIT 1
In Java it would be something like this:
TraversalDescription traversal = db.traversalDescription().depthFirst().evaluator(new PathEvaluator.Adapter<Long>() {
#Override
public Evaluation evaluate(Path path, BranchState<Long> state) {
if (path.length() == 0) return Evaluation.INCLUDE_AND_CONTINUE;
Long date = (Long) path.lastRelationship().getProperty("date");
Long stateDate = state.getState();
state.setState(date);
if (stateDate != null) {
return stateDate < date ? Evaluation.INCLUDE_AND_CONTINUE : Evaluation.EXCLUDE_AND_PRUNE;
}
return Evaluation.INCLUDE_AND_CONTINUE;
}
});
int length = 0;
Path result;
for (Path path : traversal.traverse(startNode)) {
if (path.length() > length) {
result = path;
length = path.length();
}
}

Can UNION and WITH play together?

Is there any way to use the results of a UNION in another sub-query using a WITH clause?
I'm looking for something like
(
MATCH (me:Person)-[:RATES]->(r:Rating)-[:RATED_BY]->(them:Person)
WHERE me.ident = {id} AND r.date = {date}
RETURN them
UNION ALL
MATCH (me:Person)<-[:RATED_BY]-(r:Rating)<-[:RATES]-(them:Person)
WHERE me.edent = {id} AND r.date = {date}
RETURN them
)
WITH them
RETURN them.name, COUNT( them.name) as ratingCount
ORDER BY ratingCount DESC
LIMIT 10
only nothing like this is supported by cypher.
And yes, I know that in this case I should be using
MATCH (me:Person)-[:RATES|RATED_BY]-(r:Rating)-[:RATES|RATED_BY]-(them:Person)
WHERE me.ident = {id} AND r.date = {date}
RETURN them.name, COUNT( them.name) as ratingCount
ORDER BY ratingCount DESC
LIMIT 10
which is fine and dandy, but I think that I'm going to get some more complex requests down the road where this won't work.

Resources