Reputation: 12679
I have a query criteria which looks for an array of elements ( tags_array ) to match :
User.all_in('watchlists.tags_array' => tags_array)
I'd like the criteria to be CASE-INSENSITIVE, meaning I want it match %w[Ruby Web Framework]
as well as %w[RUBY WEB FRAMEWORK]
or %w[ruby web framework]
and so on ...
Is this possible via mongoid or do I have to use external filter tricks ?
Upvotes: 1
Views: 2423
Reputation: 2511
In order to managing regexp in mongo request (find , update..)
I do this:
'p' is a variable that stores the name to search
reg = /^#{p}$/i @db['pgm'].update({'nom' => reg }....
Upvotes: 0
Reputation: 12679
Thanks to the support of Jordan and just for tracking purposes (for myself and others as well), I'll post the entire solution.
Yes, Yuriy Goldshtrakh was right, MongoDB still does not support case-insensitive query but MongoID has regex, my only doubt is regarding performance degradation as already said by "mu is too short" but I didn't check until now ... anyway here it is :
Object.const_set :Competitor, Struct.new(:html_url, :description, :watchers, :forks)
def self.find_competitors(tags_array)
competitors = []
User.all_in('watchlists.tags_array' => tags_array.map{|tag|/^#{tag}/i}).only(:watchlists).each do |u|
u.watchlists.all_in(:tags_array => tags_array.map{|tag|/^#{tag}/i}).desc(:watchers).each do |wl|
competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks)
end
end
return competitors
end
No normalization at save/create mongoid level, the tags are saved either upper or lower case.
Normalization (case-insensitive matching of tags) are realized entirely during the nested quering criteria ( it's nested because of embedded one to many model ).
If you have better idea or code, please have a post.
I'd also thanks Luiz K. for answering, even if I'll not follow that way: normalization at data level is too restrictive in my view, loosing semantic and elasticity "user" side (who actually is tagging). Anyway could be a good solution for other requirements.
Many thanks Luca G. Soave
Upvotes: 5
Reputation: 7249
This is what i've done:
def create
@noticia = Noticia.new(params[:noticia])
@noticia.tags = @noticia.conteudo.html_safe.split(' ')
@noticia.tags.each_with_index do |tag, index|
@noticia.tags[index] = @noticia.tags[index].gsub(/<\/?[^>]*>/, "")
end
i've splitted all noticia's content into 'tags', and downcased they. in my search i do the following:
def buscar
array = params[:query].split(' ')
array.each_with_index do |query, index|
array[index] = array[index].gsub(/<\/?[^>]*>/, "").downcase
end
@noticias = Noticia.where(:tags.all => array).paginate(:page => params[:page])
end
i've downcased my query search too
don't forget to index tags
field
Upvotes: 0
Reputation: 2014
I don't think mongo has support for the non case-sensitive selects, you can either normalize the data by converting it all to a specific case or use regexp finders
Upvotes: 4