I am displaying a table with Userobjects. The displayed information are:
User.firstName
User.lastName
User.email
but displayed by using user.toString() which results in the following output:
Gordon, Tomas (gordon.tomas#company.com)
Hanks, Jessica (hanks.jessica#company.com)
I want to have a filter on this list to allow people to search for specific users. These are the requirements:
1) 1 search field only
2) generic text input
currently i do the following to update the list, wheras owner is the input:
def user // input as string from the search field
def potentialUsers = User.withCriteria {
or {
ilike("firstName", '%' + user + '%')
ilike("lastName", '%' + user + '%')
ilike("email", '%' + user + '%')
}
}
this works very well when there is only 1 word of input.
what I however expect is that people will search like this:
'tom'
'gordon tomas'
'jessica#company hanks'
'tomas gordon'
... and so on
the best solution in my eyes would be to search directly in toString() but I have not figured out how to do so..
any ideas on how to filter that correctly?
Basically you have 2 options here: do it quick or do it right.
Quick) add a field to your domain class to contain the concatenation of the field values you want to search, like User.concatenated = 'Gordon Tomas gordon.tomas#company.com'. then you can fire your search like:
def potentialUsers = User.withCriteria {
user.split( /\s+/ ).each{
ilike 'concatenated', '%' + it + '%'
}
}
Right) use Lucene or a Lucene-based proper full-text search framework, like hibernate-search or grails search plugin or elastic search to index your fields, so you can fire the complex multi-word queries
Related
sqlQueryString.append(" and upper(username) like upper(:searchString) ");
This code returns data like exampleusername, exampleusername1, exampleusername12...
I want it to return data with an exact match to the username that is being searched.
For example when I put in bobJacobs (an example username), I want it to return only bobJacobs records, not other records that may contain bobJacobs in them, for example samandbobJacobs24, bobJacobs23, etc.
I've tried:
sqlQueryString.append(" and upper(username) = upper(:searchString) ");
But it doesn't work. Any solutions?
In the following Drools file, I join two queries in the when expression, and print matched results.
import com.demo.drools.*;
rule "demo"
when
$book: BlockTrade()
$buys : Trade(type=="buy") from $book.trades
$sells : Trade(type=="sell", $buys.id==id,
$buys.price==price,
$buys.trader==trader) from $book.trades
then
System.out.println("buys: " + $buys);
System.out.println("sells: " + $sells);
end
It works okay, but I want to log all unmatched trades with an unmatch reason.
For example:
Trade id=1 doesn't match because $buys.type="both" doesn't match any trades in $buys or $sells
// or
Trade id=2 doesn't match because $buys.price=50, and $buys.trader="John" doesn't match any $sells
How can it be implemented?
See this other answer. If you want to log the unmatched trades, you will need to create the rules for that.
Hope it helps,
I have a query that when given a word that starts with a one-letter word followed by space character and then another word (ex: "T Distribution"), does not return results. While given "Distribution" alone returns results including the results for "T Distribution". It is the same behavior with all search terms beginning with a one-letter word followed by space character and then another word.
The problem appears when the search term is of this pattern:
"[one-letter][space][letter/word]". example: "o ring".
What would be the problem that the LIKE operator not working correctly in this case?
Here is my query:
#Cacheable(value = "filteredConcept")
#Query("SELECT NEW sina.backend.data.model.ConceptSummaryVer04(s.id, s.arabicGloss, s.englishGloss, s.example, s.dataSourceId,
s.synsetFrequnecy, s.arabicWordsCache, s.englishWordsCache, s.superId, s.categoryId, s.dataSourceCacheAr, s.dataSourceCacheEn,
s.superTypeCasheAr, s.superTypeCasheEn, s.area, s.era, s.rank, s.undiacritizedArabicWordsCache, s.normalizedEnglishWordsCache,
s.isTranslation, s.isGloss, s.arabicSynonymsCount, s.englishSynonymsCount) FROM Concept s
where s.undiacritizedArabicWordsCache LIKE %:searchTerm% AND data_source_id != 200 AND data_source_id != 31")
List<ConceptSummaryVer04> findByArabicWordsCacheAndNotConcept(#Param("searchTerm") String searchTerm, Sort sort);
the result of the query on the database itself:
link to screenshot
results on the database are returned no matter the letters case:
link to screenshot
I solved this problem.
It was due to the default configuration of the Full-text index on mysql database which is by default set to 2 (ft_min_word_len = 2).
I changed that and rebuilt the index. Then, one-letter words were returned by the query.
12.9.6 Fine-Tuning MySQL Full-Text Search
Use some quotes:
LIKE '%:searchTerm%';
Set searchTerm="%your_word%" and use it on query like this :
... s.undiacritizedArabicWordsCache LIKE :searchTerm ...
Im new to this so here goes.
Trying to get a user called "Bob" from the MongoDb.
I have the:
UserData ud = MonConMan.instance().getDb().find(UserData.class, "name","bob").get();
The "bob" cannot be found if it has capital "Bob".
I understand i can get a List and do equalsIgnoreCase but are
there some Operators i can use?
I have users logging on and must test to see if they are registered. A user can type his name anyway he likes so must find a way to equalsIgnoreCase. Yea this is a problem, i cannot get all names and do equalsIgnoreCase, if there are like 10,000. One could of course initially save all user names in lowercase but that would destroy the visual appearance of the name.
looking at the wiki but cannot see any..
http://code.google.com/p/morphia/wiki/Query
Use java regex, like this.
String name = "bob";
Pattern pattern = Pattern.compile("^" + bob + "$", Pattern.CASE_INSENSITIVE);//This line will create a pattern to match words starts with "b", ends with "b" and its case insensitive too.
Query<UserData> query = createQuery().field("name").equal(pattern).retrievedFields(true, "id");//Replace `id` with what ever name you use in UserData for '_id'
UserData user = query.get();
if(user!=null){
//he is already registered
}
else{
//He is a new guy
}
(I am not good at regex, so you may have read about$&^somewhere. )
You should be sure that the user names you are using to validate a new user should be unique across your system.
Ended up keeping two fields like
- lowercaseusername
- originalusername
This way i could search for a user using the lowercaseusername
You can make find a name of a UserData using this code :
Query<UserData> query = createQuery().filter("name","bob");
find(query);
In my application, this code return all UserData that haves a field name with "bob" value.
The code can be this way too :
Query<UserData> query = createQuery().field("name").equal("bob");
find(query);
These codes will be in a UserDataDao that extends BasicDao, and receives in the construtor the datastore from morphia.
So I posted this question
Putting a simple expression language into java
and got a great answer about using ScriptEngine to allow the user to write javascript which I did and it seemed to work
But whilst an expression like
(artist.length>0 ? artist + '-' :'') + (album.length>0 ? album + '-' :'')
works using a full if statement does not
if(artist.length>0) {artist + ':-'} + (album.length>0 ? album + '-' :'')
You might ask why Im doing this, well I was hoping I could use an if:else if:else statement and this was a step towards that
That simply isn't valid javascript. The
<cond> ? <iftrue> : <iffalse>
is the 'expression' form of if-else, and returns the value which can be used.
if {
} else {
}
is the 'statement' version, and is used to execute code, and does NOT return a value.