Solr Search Stripping Phone Number in Database before Comparison - ruby-on-rails

I have a list of restaurants that I want to match with the restaurants in my database using phone number. The problem is that the numbers are formatted differently (i.e. (123)123-1234 or 123 123-123 or other combinations).
My current Solr search looks like this:
search = Restaurant.solr_search do
with(:phone, SunspotHelper.sanitize_term(pr.phone).gsub(/\s+/, ""))
paginate page: 1, per_page: 15
end
SunspotHelper.sanitize_term(pr.phone).gsub(/\s+/, "") will strip down my search query to just numbers. However, the values in my database still contain other non-numeric characters and thus, search.hits returns an empty array because I'm not getting any results.
Is there a way to strip my database values (:phone) before Solr does a search?
Thanks.

Configure WordDelimiterFilterFactory for your phone number field.
This will allow you to index phone data in various format and make them searchable as well.
You would not need to do any change to the database.

Related

How to use ilike for phone number filter

Hi im fetching the user input and displaying the records that matches the condition, my query will look like
customers = customers.where('customers.contact_num ilike :search', {search: "%#{options[:search_contact]}%"})
here in db the contact number is stored in string with the format (091)-234-5678 like that
on while searching the user on basis of contact number if i search like this
091 it filters the number correctly, but while searching like 0912, it doesn't display record due to the braces, so how to modify the query to neglect the ) and - while searching..
As im new to the domain please help me out
thanks in advance
What about using REGEXP_REPLACE to remove all non-digit chars from the search - something like below?
customers = customers.where("REGEXP_REPLACE(customers.contact_num,'[^[:digit:]]','','g') ilike :search", {search: "%#{options[:search_contact]}%"})
Changing the query is hard. Let's not do that.
Instead right a quick script to transforms your numbers into
1112223333 form. No formatting at all. Something like:
require 'set';
phone = "(234)-333-2323"
numbers = Set.new(["1","2","3","4","5","6","7","8","9","0"])
output = phone.chars().select{|n| numbers.include?(n)}.join("")
puts output
=> "2343332323"
Then write a little function to transform them into display form for use in the views.
This will make your query work as is.

Searching for matching records in a field saved as a hash in PostgreSQL?

I have an active record SearchSuggestion that has a title:text field for storing values for different languages in a single hash that looks like so:
#<SearchSuggestion :id 1, link: "/search/shoes", title: {"en"=>"Women's shoes", "ko"=>"여성 신발", "ru"=>"Женская Обувь", "fr"=>"Chaussures De Femme"}>
and I'm fetching records that match the given input in the following way: all of the given words contained in all records' title fields, starting only from the start of each word the following way:
query = params[:q].split(" ").map{|s| s.prepend('(?:.*\m')}.map{|s| s.concat(')')}.join('')
SearchSuggestion.where("title ~* ?", query).limit(10).pluck(:title)
The problem is that this gives me matches from the whole field, and I want just the ones for the current selected language. So if I have languages that are using the same alphabet - I get unrelated results e.g - if I start typing "cha" this will return "Women's shoes" by finding the French suggestion as a match. Also if I type "en" - I get all of the existing records as a result, because they match the key for "en" language.
Is there any way I can specify the hash's key that I only want to search within?

Query in a string column for one of the value in an array like multiple OR (using full text search)

In a rails 4 app, in one model I have a column containing multiple ids as a string with comma separated values.
"123,4568,12"
I have a "search" engine that I use to retrieve the records with one or many values using the full text search of postgresql I can do something like this which is very useful:
records = MyModel.where("my_models.col_name ## ?", ["12","234"])
This return all the records that have both 12 and 234 in the targeted column. The array comes from a form with a multiple select.
Now I'm trying to make a query that will find all the records that have either 12 or 234 in there string.
I was hopping to be able to do something like:
records = MyModel.where("my_models.col_name IN (?)", ["12","234"])
But it's not working.
Should I iterate through all the values in the array to build a query with multiple OR ? Is there something more appropriate to do this?
EDIT / TL;DR
#BoraMa answer is a good way to achieve this.
To find all the records containing one or more ids referenced in the request use:
records = MyModel.where("my_models.col_name ## to_tsquery(?)", ["12","234"].join('|'))
You need the to_tsquery(?) and the join with a single pipe |to do a OR like query.
To find all the records containing exactly all the ids in the query use:
records = MyModel.where("my_models.col_name ## ?", ["12","234"])
And of course replace ["12","234"] with something like params[:params_from_my_form]
Postgres documentation for full text search
If you already started to use the fulltext search in Postgres in the first place,I'd try to leverage it again. I think you can use a fulltext OR query which can be constructed like this:
records = MyModel.where("my_models.col_name ## to_tsquery(?)", ["12","234"].join(" | "));
This uses the | operator for ORing fulltext queries in Postgres. I have not tested this and maybe you'll need to do to_tsvector('my_models.col_name') for this to work.
See the documentation for more info.
Suppose your ids are :
a="1,2,3,4"
You can simply use:
ModelName.find(a)
This will give you all the record of that model whose id is present in a.
I just think a super simple solution, we just sort the ids in saving callback of MyModel, then the query must be easier:
class MyModel < ActiveRecord::Base
before_save :sort_ids_in_col_name, if: :col_name_changed?
private
def sort_ids_in_col_name
self.col_name = self.col_name.to_s.split(',').sort.join(',')
end
end
Then the query will be easy:
ids = ["12","234"]
records = MyModel.where(col_name: ids.sort.join(',')

Get all the rows raleted with a specific string

I am using rails with a postgresql db, and I would like to know which is the best solution, in getting all the rows which are similar with a string.
string format: domain.com or domain.com/uk or subdomain.domain.com
db column format : http://www.test.com/All-test/test1/test2-test3/
So I would like to get from my table all the rows which are matching with my string.
Currently I have a script which is going through all the rows in my table, and taking the column values, from where it takes the host and compares it with the string.
Thank you
Looks like the LIKE function is what you want to use. You can use in in an ActiceRecord query like this:
search_string = "domain.com"
YourModel.where("db_column LIKE ?", "%#{search_string}%").first
You might need to refine the search, but the link above should give you all the tools you need

FullTextIndex in NexusDB, How to tokenize the searchstring

We are using NexusDB for a small database. We have a table with a FulltextIndex defined on it.
The index is configured with the following options:
Character separator
ccPunctuationDash
ccPunctuationOther
The user enters a search text in an edit box, and then an SQL statement is constructed with the following WHERE clause (%s substituted with the Editbox.text of course):
WHERE CONTAINS(FullIdx, ''%s'')
When the user enters multiple words in the editbox this goes wrong as the two separate words should have been embedded in the WHERE clause like this:
WHERE CONTAINS(FullIdx, 'word1' and 'word2')
So i have to parse the textbox value, scan it for spaces and split the text at those points. That made me wonder if it was possible to parse the search text for every setting of the fulltextindex, using the actual definition of the fulltextindex to create the correct where clause.
So if ccPunctuationDash is enabled in the FulltextIndex definition, than the search text is also split on a '-'.
If you think of it, it is exactly the same process as when the index is created and all strings are tokenized ...
My question: what is the easiest way of tokenizing a searchstring according to the settings of a FUlltextIndex?
The easiest way is... to create an empty #temporary table with a string field, with the same fulltext index settings as your real table. Set the TnxTable.Options to include dsoAddKeyAsVariantField. Load the string to tokenize into the string field, then view the table indexed by the fulltext index. Presto, you get an extra field displayed, which is the sorted tokens. You can now iterate over the table to read the tokens.

Resources