Case insensitive searching for words in mongoid - ruby-on-rails

Is there a way to set an attribute in mongoid for case insensitive searches?
Lets say that somebody has a username: IAmGreat and I want to find the users data using their unique username without butchering it and changing it to iamgreat.
Thanks

Actually you can search case insensitive. But you have to search with an regex!
Here is an example how I'm using it at http://zeit.io
User.where(email: /\A#{Regexp.escape(email)}\z/i).first
With the / you are starting and ending the regex. The i after the regex means case insensitive. \A Means the string has to start with the search string and \z means the string has to end with the search string. This is important if you are looking for an exact match.

You can even try something like:
User.where(username: /#{username}/i).first

if you are using rails or mongoid you can try the ff:
#user = User.where({:username => /.*#{name}.*/i })

Why not just down a User.login.downcase (or whatever your model/attribute combination is) when making the comparison? This will leave the capitalization in the DB as-is, but downcase the field just for comparison.

If your application doesn't need to store user-input as case-sensitive, just convert the input to uppercase or lowercase on the way in. Example,
username = params[:username].to_s.downcase
Otherwise, if performance is an issue for you (case-insensitive regex cannot take advantage for indexes) the right way to go about it is to store a backup field for username
field :username_downcase
And then do the query:
User.where(username_downcase: params[:username].to_s.downcase)

Related

Handling special chars in a case insensitive search

I am using:
c.customerName =~ '(?i).*$q.*'
in order to find insensitive case any kind of customername and this is working absolutely fine for all standard character. In German unfortunately there are special chars e.g. like Ä,Ö,Ü. In this cases the cypher statement is case sensitive, e.g. if we have two customer names like Ötest and ötest it will find only one of them depending if you type a lower or an upper Ö.
Anyone has a hint what I can do to expand the insensitive case search also on such special chars?
EDIT: The problem exists also when you have a name including e.g. a '&' - you'll find e.g. the company D&A Construction when you type 'D&' - the moment you add a thrid character 'D&A' the search fails and no result is shown. Any idea?
You need to add a 'u' in your regex to transform it in a case-insensitive unicode regex. Like this:
c.customerName =~ '(?ui).*$q.*'
Works here:
From this StackOverflow question.

Neo4j - search like query with non english characters

Is there an option in neo4j to write a select query with where clause, that ignores non-latin characters ?
MATCH (places:Place)
WHERE (places.name =~ '.*(?ui)Fabergé.*')
RETURN places
I have place with Fabergé name in graph and i want to find it when user type Fabergé or Faberge without this special character.
I'm not aware of an easy way to do this directly with a regex match in Cypher.
One possible workaround is to store the string in question in a normalized form in a second property e.g. place.name_normalized and then compare it with the normalized search string. Of course normalization needs to be done on client side, see another SO question on how to achive this: Remove diacritical marks (ń ǹ ň ñ ṅ ņ ṇ ṋ ṉ ̈ ɲ ƞ ᶇ ɳ ȵ) from Unicode chars

Case Insensitive Search with Neo4jClient

Just an quick and easy one, I need to be able to search our database minus the case sensitivity, I know how to do it, just not with the Neo4jClient. Here's the code:
client.Cypher
.Match("(person:Person)")
.Where((Person person) => person.Email == search)
where 'search' is a parameter of type string that is passed to the method. I have read that using =~ '(?i)text' works, but that doesn't allow me to pass in the parameter, and I have tried this:
client.Cypher
.Match("(person:Person)")
.Where((Person person) => person.Email =~ "(?i){terms}")
.WithParam("terms",search)
But it doesn't like this.
I would like to be able to search without case, and if possible at the same time, using LIKE (or ILIKE as it seems to be for pattern matching).
Thanks
EDIT & ANSWER
The final code ended up as this:
return client.Cypher
.Match("(person:Person)")
.Where("person.Email =~ {terms}")
.OrWhere("person.Name =~ {terms}")
.WithParam("terms", "(?ui).*" + search + ".*")
.Return<Person>("person").Results.ToList();
Which does exactly what I want it to.
Also took the advice of a lowercase field with the value in, we already have one in the account so that logon names are not case sensitive, I am going to do this on the email and name fields, seems better than using toLower() (either in Cypher or in C#)
So thank to #Stefan Armbruster for his help.
You cannot have partial parameters. Instead add (?i) to the parameter value:
query: person.Email =~ term
parameter: term = "(?i)<myvalue"
Note 1: You need to use (?ui) for gracefully dealing with non-ascii case sensitivity (e.g. German umlauts).
Note 2: the =~ operator is not backed by an index, so the query above will touch every Person node and apply the regex to the property value. In Neo4j 2.3 there will be a index backed LIKE which supports string prefix matches.
If you want to use index based case insensitive search, the recommended approach is to store the property value converted to lower case (Cypher has a toLower function) and then do a exact match on the lower cased search value.

Ruby On Rails searching database for word

I am new to rails. I am trying to search a database in MySQL where the term I am searching may be one word in the column string. For example if the cell was "this is a very lovely day" then I would like to be able to call that object by searching for the word 'lovely'
Thank you.
You need to do a LIKE query. (i.e. foo LIKE %bar%) The % represents a wildcard operator. bar% would be "starts with bar" and %bar% would be "contains bar." Note that contains searches cannot use column indexes and will be slow.
Suppose you had a Day class with the attribute description. In that case, you would do
Day.where("description LIKE '%lovely%')
by using Arel
days = Day.arel_table
Day.where(days[:description].matches("%lovely%"))

Mongoid: query a range of ASCII characters

I have a collection with a string field called named in my Mongoid based class. I'd like to be able to query for all documents that begin with the letters in the a through f in the name field, case insensitive. What's the best way to do this through Mongoid? I'm assuming the interface is similar to ActiveRecord, so if it can be done in ActiveRecord, it can probably be done through Mongoid as well.
This will do the trick
Yourcollection.where(:name => /^[a-f]/i )
i - for case insensitive

Resources