setFilter() with a string wildcard? - java

I see an example of doing a partial string search on the GAE google group (this thread):
String term1 = "cow";
String term2 = "horse";
Query q;
q.setFilter("name.matches('" + term1 + "%')");
so this works like:
"Find all objects of the class where property 'name' starts with term1"
so that would match stuff like:
cowfoo
cowgrok
cowetc
right? I could then replace term1 with term2, and find all instances that begin with 'horse'. Is there a doc that explains this anymore? I just want to check this is how it really works before I make a decision on how to store some strings for my data model,
Thanks

I can't find the docs which present the prefix matching syntax you presented, but your logic is sound. And it looks like the syntax is supported based on the google group message you cited.
For the Python runtime, I would perform a prefix match by using an inequality filter. You can also do this on the Java runtime like this (and this is probably how the % syntax is implemented):
// prefix is some string object
q.setFilter("my_string_field >= :1 && my_string_field < :2");
q.execute(prefix, (prefix + "\ufffd"));

Related

Fetching data with Special Characters from HQL

I have a search functionality that is implemented on my current project, I am using HQL for the repo method - Everything is okay except searching for special characters for some reason HQL is not escaping it.
#Query("SELECT f FROM Item f WHERE f.id=:id AND f.itemNm LIKE %:itemNm %")
Item findByItemNm(#Param("itemNm ") String itemNm, #Param("id") Long id);
The String search I am sending is
abc_xyz(YYYYMM[t-2]-YYYYMM[t-1])_[xyz]HU.xlsx
Debugging Steps
Before sending to the Repo - I did replace all the special characters with the following -newsearchString is the one thatt is being passed to the repo
String newsearchString = searchString.replaceAll("(?=[]\\[+&|!(){}^\"~*?:\\\\_]) ", "/");
I have also tried it without replacing the special characters- It is not being returned
How do you escape characters in HQL?
Here is the solution for your problem...It should work for your need.
1) Find and replace all your escape characte, and replaced by "\\"
Example: [hi]_mysearch should be replaced like \\[hi\\]_mysearch
2) Change your repo query like below
#Query("SELECT f FROM Item f WHERE f.id=:id AND f.itemNm LIKE %:itemNm % escape '\\'")
Item findByItemNm(#Param("itemNm ") String itemNm, #Param("id") Long id);
HQL does not have regular expressions out of the box. You'd have to modify the Dialect for your specific database to add that functionality. (Oracle example)
If you're just trying use like with the % wildcard, then you can do the following:
String itemNm = "abc_xyz(YYYYMM[t-2]-YYYYMM[t-1])_[xyz]HU.xlsx";
Query q = session.createQuery("from Item where itemNm like :itemNm ";
q.setString("itemNm","%"+itemNm+"%");

neo4j escaping for regular expressions

I receive a user input keyword and want to use it to search my database. I built a query that looks something like this:
db.execute("MATCH (n:User) WHERE n.firstname CONTAINS {keyword} OR n.lastname CONTAINS {keyword} RETURN n.username", params);
But this isn't case sensitive, so I thought of manually building the expression and using regular expressions, sort of as follows:
db.execute("MATCH (n:User) WHERE n.firstname =~ '(?i).*" + keyword + ".*' OR n.lastname =~ '(?i).*" + keyword + ".*' RETURN n.username");
I'm looking either for a function for escaping the regex or a better solution for making the query case-insensitive. Any ideas?
I would suggest storing the properties as all lowercase (or uppercase) and then using the Cypher lower() function to convert user input to lowercase for comparison.
Add lowercase name properties
MATCH (n:User)
SET n.lowerFirstName = lower(n.firstname),
n.lowerLastName = lower(n.lastname)
Find lower case matches based on user input
db.execute("MATCH (n:User) WHERE n.lowerFirstName CONTAINS lower({keyword}) OR n.lowerLastName CONTAINS lower({keyword}) RETURN n.username", params);

Mockrunner(Java) query with Regex

I am using Mockrunner to mock Sql DB for my unit tests. Following is my query:-
"select * from table where userId in (" + userIds + ")"
Now my userIds is state dependent. I don't need my test cases dependent on the arrangement inside the list - userIds. So I don't need exact match but regex matching. I have already enabled regex matching by below code:-
StatementResultSetHandler statementHandler = connection.getStatementResultSetHandler();
usersResult = statementHandler.createResultSet("users");
statementHandler.setUseRegularExpressions(true);
//How to write this regex query?
statementHandler.prepareResultSet("select * from table where userId in .*", campaignsResult);
But as it is noted, I have no idea about the regex syntax supported by Mockrunner.
Edit: I unable to match queries like "Select * from tables" with "Select * from tab .*". So It has to do something with the way I using regex with Mockrunner
There are some helpful examples available here. For instance:
public void testCorrectSQL() throws Exception {
MockResultSet result = getStatementResultSetHandler().createResultSet();
getStatementResultSetHandler().prepareResultSet("select.*isbn,.*quantity.*", result);
List orderList = new ArrayList();
orderList.add("1234567890");
orderList.add("1111111111");
Bookstore.order(getJDBCMockObjectFactory().getMockConnection(), orderList);
verifySQLStatementExecuted("select.*isbn,.*quantity.*\\(isbn='1234567890'.*or.*isbn='1111111111'\\)");
}
From this, I surmise that it's using standard Java regex syntax. In which case, you probably want:
prepareResultSet("select \\* from table where userId in \\(.*\\)", campaignsResult);
...or perhaps more succinctly (and depending upon exactly how fine-grained your tests need to be):
prepareResultSet("select .* from table where userId in .*", campaignsResult);
The main caveat to be aware of when enabling the regex matching is that any literal special characters that you want in your query (such as *, (, and ) literals) need to be escaped in your regex before it will work properly.

Lucene: Is there any way to know which subqueries have hit the document?

I have a MemoryIndex created like this.
```
Version version = Version.LUCENE_47;
Analyzer analyzer = new SimpleAnalyzer(version);
MemoryIndex index = new MemoryIndex();
index.addField("text", "Readings about Salmons and other select Alaska fishing Manuals", analyzer);
```
Then, I have a query containing a number of sub-query which is created from a set of concepts (including id, name, description). Right now I have to loop for every concept, generate a query, and finally check if it is matched => if it is, I append it to a string which is used to store matches
```
for (Concept concept : concepts) {
Query query = queryGenerator.getQueryForConcept(concept);
float score = query != null ? index.search(query) : 0.0f;
if (score > 0) {
matches.append(sep + concept.getId() + "|" + concept.getName());
sep = "|";
}
}```
The problem is: the number of concepts is growing larger and larger, which affects the performance. Is there anyway that I can create a one single query and compare to a document, and find out what concepts have been hit the document?
I tried using BooleanQuery as a whole, then add all subquery which derrived from concept into it. It matches but don't know which subquery hits, and even if we do, how do we put the details like "id", and "name" of a concept into it?
Much appreciate all answers

Replace querystring attribute value in java using regex

I want to replace querystring value but it's creating some problems:
Problem 1: Its Removing the "&" symbol after replacing
String queryString = "?pid=1&name=Dell&cid=25";
String nQueryString=queryString.replaceAll("(?<=[?&;])pid=.*?($|[&;])","pid=23");
System.out.println(nQueryString);
output of above example
?pid=23name=Dell&cid=25
you can see its removed the "&" after pid
Problem 2: Its not working if I removed the "?" symbol from the queryString variable.
String queryString = "pid=1&name=Dell&cid=25";
String nQueryString=queryString.replaceAll("(?<=[?&;])pid=.*?($|[&;])","pid=23");
System.out.println(nQueryString);
output of above example
?pid=1&name=Dell&cid=25
We can say the regex is not working, So anyone can suggest me better regex which completely fulfill my requirements.
queryString.replaceAll("(?<=[?&;])pid=.*?(?=[&;])", "pid=23")
Difference is that I'm using a positive-lookahead: (?=[&;]), which is zero-length, making it atomic, and is not actually included in the replacement via replaceAll(), just like your original positive-lookbehind is not replaced.
Alternatively, we can match until a & or ; is found, but not included in the replacement, ie:
queryString.replaceAll("(?<=[?&;])pid=[^&;]*", "pid=23")
[^&;] : ^ negates the following: &;, so [^&;]* will match until a ; or & is encountered.
Yours does not work because ($|[&;]) is a non-atomic group, specifically a capturing group, and thus is included in the replacement. NB: a non-capturing group (?:$|[&;]) would also fail here.
To your final note, you're using a positive look-behind for ?, &, and ;, so by removing the ?, it will no longer match, which makes sense.
Use this regex instead:
String nQueryString = queryString.replaceAll("(?<=[?&;])pid=[^&]*", "pid=23");
//=> ?pid=23&name=Dell&cid=25
Here [^&]* is called negation matching pattern, that will match query string value until & is found OR else end of string is found thus leaving rest of the query string un-effected.

Categories

Resources