hibernate Query to find record based on substring - java

I want to make a Hibernate query to check if a string contains a substring.
Suppose a user class having id,name,info.
info is String which contain multiple substrings.
For example info contains strings like "hi I am from Pune".
I want to read all record which contain Pune as substring.
I tried using like query but not working.
Criteria criteria = session.createCriteria(Post.class);
criteria.add(Restrictions.like("content",contentStringToLook));
users = (List<Post>)criteria.list();

Try modifying the restriction as follows:
criteria.add(Restrictions.like("content","%"+contentStringToLook+"%"));

You can use this :
criteria.add(Restrictions.like("content",contentStringToLook, MatchMode.ANYWHERE))
There's also MatchMode.START, .END, and .EXACT.

Related

Is there such a query for mongodb?

I need to do a query on mongoDB due to I am developing in Java with Spring Boot and MongoDB. I know that this command is for arrays:
#Query("{ 'skills' : {$all : ?0}} ")
List<DataCV2> findAllSkillsInCV(ArrayList<String> skillsOfCV);
This query let me to find if all fields of the arraylist "skillsOfCV" are in the arraylist called "skills"
However, I am trying to pass an arraylist as "skillsOfCV" to compare all the fields with a string field in database.
#Query("{ 'experienceCV' : {$all : ?0}} ")
List<DataCV2> findAllExperienceInCV(ArrayList<String> experienceOfCV);
The field "experienceCV" is a string one, and I want to compare if this string field contains all the fields of the arraylist "experienceOfCV".How could I do that?
It is not possible to match String and List<String> using $all in a straightforward way.
The best bet is that use String field for the method and do the conversion programmatically.
Or else you can give a try with aggregation framework which has many useful aggregation operators.

How to get exact search using lucene

When we searching like "prd gem". It returns all results names with prd gem.
but when we search only "prd", it returns all results with prd in it like prd,prd gem, prd time etc. Why not exact search now?
Following was code in picture:
luceneQuery = queryBuilder.phrase()
.onField("productId")
.andField("productName").andField("refId")
.sentence(searchText)
.createQuery();
Exact search is working fine with the name having space in it like if i search "Prd Gem", it shows only one product with name "Prd Gem", but when i search only a word like "prd", exact search is not working, it shows all product like "prd","prd gem"
So what changes need to be done with above code to implement the same?
Thats because you are "tokenizing" the data in the lucene index.
Lucene by default will try to break the strings into tokens in order to allow and speed up such searches.
I assume you are using the latest hibernate. Can you try to annotate the "productName" field with the following:
#Field(name = "productName", index = Index.YES, analyze = Analyze.NO, norms = Norms.NO)
The "analyze = Analyze.no" part should disable this feature.

jpql left join fetch not returning results for like

In a spring mvc app using hibernate and MySQL, I have written the following query method to return a list of names with patients:
#SuppressWarnings("unchecked")
public Collection<Person> findPersonByLastName(String ln) throws DataAccessException{
Query query = this.em.createQuery("SELECT DISTINCT pers FROM rimPerson pers left join fetch pers.names nm WHERE nm.family LIKE :lnm");
query.setParameter("lnm", ln);
return query.getResultList();
}
This is producing the following hibernate sql:
Hibernate:
select distinct
person0_.hppid as hppid1_340_0_,
names1_.HJID as HJID1_89_1_,
person0_2_.classCode_HJID as classCod2_339_0_,
person0_1_.administrativeGenderCode_HJID as administ2_341_0_,
person0_1_.birthTime_HJID as birthTim3_341_0_,
names1_.DELIMITER_ as DELIMITE2_89_1_,
names1_.FAMILY as FAMILY3_89_1_,
names1_.named_entity_hppid as named5_89_1_,
names1_.SUFFIX as SUFFIX4_89_1_,
names1_.name_entity_HJID as name9_340_0__,
names1_.HJID as HJID1_89_0__
from
rim_person person0_ inner join rim_living_subject person0_1_ on person0_.hppid=person0_1_.hppid
inner join rim_entity person0_2_ on person0_.hppid=person0_2_.hppid
inner join rim_infrastructure_root person0_3_ on person0_.hppid=person0_3_.hppid
left outer join EN names1_ on person0_.hppid=names1_.name_entity_HJID
where names1_.FAMILY like ?
When I call the above jpql method with the following command, it returns zero results:
this.myappService.findPersonByLastName("");
I also get zero results when I cut and past the above generated hibernate code into the MySQL command line client and replace ? with ''.
If, however, I remove the where names1_.FAMILY like ? from the hibernate generated sql above and place the shortened sql into the MySQL command line client, I get four results, eachof which has a value for the lastname field.
How can I change the jpql so that it generates a hibernate query that returns the four results when `` is passed as the empty string parameter? I want the result set to include every result when the user gives empty input, but to give filtered results when the user types in any given text input.
The typical reason that like fails to do what you think it ought to do is to forget to put a wildcard in the pattern string. For example, if you want to match all user names that begin with 'Code' you must do something like name like 'Code%', NOT name like 'Code'. You can control exactly what your predicate matches with careful placement of %s in your string.
Try this to see all entities no matter what the value in family:
this.myappService.findPersonByLastName("%");
It is kinda cheesy to have the caller of findPersionByLastName have to put in the % wildcard. A better implementation is to have the caller specify which last name they are looking for, and then have the code that constructs the query put the wildcard in the right place. When you are looking for last names, you might do something like this:
query.setParameter("lnm", "%" + ln);
That would match anything that ends with the parameter that is passed to the method.

How to query a clause for solr java client?

I am now using solr to query .I want to find all the documents whose key "title" contains text "Bifidobacterium bifidum" or key "abstract" contains text "Bifidobacterium bifidum".So , I write my query like below:
String queryCondition = "title:*Bifidobacterium bifidum* OR abstract:*Bifidobacterium bifidum*";
From the result ,I find out that the returned result is not what I want ,documents whose title contains "Bifidobacterium" or "bifidum" , or whose title contains "Bifidobacterium" or "bifidum" are all returned . So , my question is ,how should I write my query to satisfy my query need?
The * is special symbol, a wildcard. Similar to regular expressions, it tells Solr to match everything. So querying for bifidum* would return everything that starts with bifidum. Not what you want, right?
When reading about Solr's query syntax in the manual, you will find a section named Specifying Terms for the Standard Query Parser there is written
A phrase is a group of words surrounded by double quotes such as "hello dolly"
This is what you need ...

How to do a Multi field - Phrase search in Lucene?

Title asks it all... I want to do a multi field - phrase search in Lucene.. How to do it ?
for example :
I have fields as String s[] = {"title","author","content"};
I want to search harry potter across all fields.. How do I do it ?
Can someone please provide an example snippet ?
Use MultiFieldQueryParser, its a QueryParser which constructs queries to search multiple fields..
Other way is to use Create a BooleanQuery consisting of TermQurey (in your case phrase query).
Third way is to include the content of other fields into your default content field.
Add
Generally speaking, querying on multiple fields isn’t the best practice for user-entered queries. More commonly, all words you want searched are indexed into a contents or keywords field by combining various fields.
Update
Usage:
Query query = MultiFieldQueryParser.parse(Version.LUCENE_30, new String[] {"harry potter","harry potter","harry potter"}, new String[] {"title","author","content"},new SimpleAnalyzer());
IndexSearcher searcher = new IndexSearcher(...);
Hits hits = searcher.search(query);
The MultiFieldQueryParser will resolve the query in this way: (See javadoc)
Parses a query which searches on the
fields specified. If x fields are
specified, this effectively
constructs:
(field1:query1) (field2:query2)
(field3:query3)...(fieldx:queryx)
Hope this helps.
intensified googling revealed this :
http://lucene.472066.n3.nabble.com/Phrase-query-on-multiple-fields-td2292312.html.
Since it is latest and best, I'll go with his approach I guess.. Nevertheless, it might help someone who is looking for something like I am...
You need to use MultiFieldQueryParser with escaped string. I have tested it with Lucene 8.8.1 and it's working like magic.
String queryStr = "harry potter";
queryStr = "\"" + queryStr.trim() + "\"";
Query query = new MultiFieldQueryParser(new String[]{"title","author","content"}, new StandardAnalyzer()).parse(queryStr);
System.out.println(query);
It will print.
(title:"harry potter") (author:"harry potter") (content:"harry potter")

Categories