Passing parameter to Match query in Neo4j using Spring - spring-boot

I am trying to compare node name from Neo4j database with given technology name. I am doing using Spring Application.
#Query("MATCH (n) WHERE n.name =~ '(?i){0}' RETURN n.name")
String getTechnology(String technologyname);
Request is like
MATCH (n)
WHERE n.name =~ '(?i){0}'
RETURN n.name
with params {0=AVM}.
But it's returning null. However, if I do it actual technology name it's working fine.

Pass the parameter as WHERE n.name =~ {0}. What's happening is that the parameter isn't substituted from within the string, so the parameter has no binding in the query, and instead you're searching for the string literal "{0}" which always fails.
If you want to pass a regex as a parameter, you'll need to put the "(?i)" part in the string getting passed, effectively letting your code decide the regex, not just a string inside of it.

You need to separate the regular expression part from the parameter part like this:
#Query("MATCH (n) WHERE n.name =~ '(?i)' + {0} RETURN n.name")
String getTechnology(String technologyname);
As You'd concatenate in Neo4j.

Related

Jmeter contains string match

Is it possible to use contains instead of == in jmeter?
Eg:
$.employees[?(#.lastName == 'Smith')].firstName
I would like to use contains 'Smith'
There is =~ operator which returns the node(s) which match the regular expression.
So if you amend your query to be something like:
$.employees[?(#.lastName =~ /.*smith.*?/i)].firstName
it will return first names of the employees where lastName contains smith anywhere and it will be case-insensitive.
More information:
JsonPath Filter Operators
JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios

Jackrabbit XPath Query: UUID with leading number in path

I have what I think is an interesting problem executing queries in Jackrabbit when a node in the query path is a UUID that start with a number.
For example, this query work fine as the second node starts with a letter, 'f':
/*/JCP/feeadeaf-1dae-427f-bf4e-842b07965a93/label//*[#sequence]
This query however does not, if the first 'f' is replaced with '2':
/*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[#sequence]
The exception:
Encountered "-" at line 1, column 26.
Was expecting one of:
<IntegerLiteral> ...
<DecimalLiteral> ...
<DoubleLiteral> ...
<StringLiteral> ...
... rest omitted for brevity ...
for statement: for $v in /*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[#sequence] return $v
My code in general
def queryString = queryFor path
def queryManager = session.workspace.queryManager
def query = queryManager.createQuery queryString, Query.XPATH // fails here
query.execute().nodes
I'm aware my query, with the leading asterisk, may not be the best, but I'm just starting out with querying in general. Maybe using another language other than XPATH might work.
I tried the advice in this post, adding a save before creating the query, but no luck
Jackrabbit Running Queries against UUID
Thanks in advance for any input!
A solution that worked was to try and properly escape parts of the query path, namely the individual steps used to build up the path into the repository. The exception message was somewhat misleading, at least to me, as in made me think that the hyphens were part of the root cause. The root problem was that the leading number in the node name created an illegal XPATH query as suggested above.
A solution in this case is to encode the individual steps into the path and build the rest of the query. Resulting in the leading number only being escaped:
/*/JCP/_x0032_eeadeaf-1dae-427f-bf4e-842b07965a93//*[#sequence]
Code that represents a list of steps or a path into the Jackrabbit repository:
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.util.ISO9075;
class Path {
List<String> steps; //...
public String asQuery() {
return steps.size() > 0 ? "/*" + asPathString(encodedSteps()) + "//*" : "//*";
}
private String asPathString(List<String> steps) {
return '/' + StringUtils.join(steps, '/');
}
private List<String> encodedSteps() {
List<String> encodedSteps = new ArrayList<>();
for (String step : steps) {
encodedSteps.add(ISO9075.encode(step));
}
return encodedSteps;
}
}
Some more notes:
If we escape more of the query string as in:
/_x002a_/JCP/_x0032_eeadeaf-1dae-427f-bf4e-842b07965a93//_x002a_[#sequence]
Or the original path encoded as a whole as in:
_x002f_a_x002f_fffe4dcf0-360c-11e4-ad80-14feb59d0ab5_x002f_2cbae0dc-35e2-11e4-b5d6-14feb59d0ab5_x002f_c
The queries do not produce the wanted results.
Thanks to #matthias_h and #LarsH
An XML element name cannot start with a digit. See the XML spec's rules for STag, Name, and NameStartChar. Therefore, the "XPath expression"
/*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[#sequence]
is illegal, because the name test 2eead... isn't a legal XML name.
As such, you can't just use any old UUID as an XML element name nor as a name test in XPath. However if you put a legal NameStartChar on the front (such as _), you can probably use any UUID.
I'm not clear on whether you think you already have XML data with an element named <2eead...> (and are trying to query that element's descendants); if so, whatever tool produced it is broken, as it emits illegal XML. On the other hand if the <2eead...> is something that you yourself are creating, then presumably you have the option of modifying the element name to be a legal XML name.

spring mongo creating like query

I can match starting of string i.e clo with keywords and it gives me correct result db.post.find({"keywords":"/^clo/"}).pretty() When I tried to write same query using spring mongo.It not working properly. It gives result as % string %. i.e. matches anywhere in string. I am trying to match only at starting . my code is
String pattern = "/^" + keyword + "/";
Criteria criteria2 = Criteria.where("keywords").is(keyword).regex(pattern);
Where I am missing ?
You can do it like this:
Query.query(Criteria.where("keywords").regex("^clo"))
Or use it as native query:
new BasicQuery("{'keywords' : '/^clo/'}")
Method is() provides the full equals, regex() has to be without / wrappers.
That's is your issue.

How to query a Mongoid Regexp Field?

I want to create a regex field in my Mongoid document so that I can have a behavior something like this:
MagicalDoc.create(myregex: /abc\d+xyz/)
MagicalDoc.where(myregex: 'abc123xyz')
I'm not sure if this is possible and what kind of affect it would have. How can I achieve this sort of functionality?
Update: I've learned from the documentation that Mongoid supports Regexp fields but it does not provide an example of how to query for them.
class MagicalDoc
include Mongoid::Document
field :myregex, type: Regexp
end
I would also accept a pure MongoDB answer. I can find a way to convert it to Mongoid syntax.
Update: Thanks to SuperAce99 for helping find this solution. Pass a string to a Mongoid where function and it will create a javascript function:
search_string = 'abc123xyz'
MagicalDoc.where(%Q{ return this.myregex.test("#{search_string}") })
The %Q is a Ruby method that helps to escape quotes.
regexp is not a valid BSON type, so you'll have to figure out how Mongoid represents it to devise a proper query.
Query String using Regex
If you want to send MongoDB a regular expression and return documents MongoDB provides the $regex query operator, which allows you to return documents where a string matches your regular expression.
Query Regex using String
If you want to sent Mongo a string and return all documents that have a regular expression that matches the provided string, you'll probably need the $where operator. This allows you to run a Javascript command on each document:
db.myCollection.find( { $where: function() { return (this.credits == this.debits) } } )
You can define a function which returns True when the provided string matches the Regex stored in the document. Obviously this can't use an Index because it has to execute code for every document in the collection. These queries will be very slow.

What is Ruby doing with gsub here?

I'm working on converting code from Ruby to Node.js. I came across these lines at the end of a function and I'm curious what the original developers were trying to accomplish:
url = url.gsub "member_id", "member_id__hashed"
url = url.gsub member_id, member_id_hashed
url
I'm assuming that url at the end is Ruby's equivalent to return url;
as for the lines with gsub, from what I've found online that's the wrong syntax, right? Shouldn't it be:
url = url.gsub(var1, var2)?
If it is correct, why are they calling it twice, once with quotes and once without?
gsub does a global substitute on a string. If I had to guess, the URL might be in the form of
http://somewebsite.com?member_id=123
If so, the code has the following effect:
url.gsub "member_id", "member_id__hashed"
# => "http://somewebsite.com?member_id__hashed=123"
Assuming member_id = "123", and member_id_hashed is some hashed version of the id, then the second line would replace "123" with the hashed version.
url.gsub member_id, member_id_hashed
# => "http://somewebsite.com?member_id__hashed=abc"
So you're going from http://somewebsite.com?member_id=123 to http://somewebsite.com?member_id__hashed=abc
Documentation: https://ruby-doc.org/core-2.6/String.html#method-i-gsub
I'm assuming that the url at the end is Ruby's equivalent to return url;
If that code is part of a method or block, indeed, the line url is the value returned by the method. This is because by default a method in Ruby returns the value of the last expression that was evaluated in the method. The keyword return can be used (as in many other languages) to produce an early return of a method, with or without a return value.
that's the wrong syntax, right? shouldn't it be
url = url.gsub(var1, var2)?
The arguments used to invoke a method in Ruby may stay in parentheses but they may, as well, be listed after the method name, without parentheses.
Both:
url = url.gsub var1, var2
and
url = url.gsub(var1, var2)
are correct and they produce the same result.
The convention in Ruby is to not put parentheses around method arguments but this is not always possible. One such case is when one of the arguments is a call of another method with arguments.
The parentheses are then used to make everything clear both for the interpreter and the readers of the code.
If it is correct, why are they calling it twice, once with quotes and once without?
There are two calls of the same method, with different arguments:
url = url.gsub "member_id", "member_id__hashed"
The arguments of url.gsub are the literal strings "member_id" and "member_id__hashed".
url = url.gsub member_id, member_id_hashed
This time the arguments are the variables member_id and member_id_hashed.
This works the same in JavaScript and many other languages that use double quotes to enclose the string literals.
String#gsub is a method of class String that does search & replace in a string and returns a new string. It's name is short of "global substitute" (it replaces all occurrences). To replace only the first occurrence use String#sub.

Resources