Elasticsearch match field=value (not contains) - ruby-on-rails

I have problem while searching through elasticsearch.
I have index product with fields title and gender
When I make query with default_field: title I need to get results only with gender=male (not female or others)
query: dress AND gender:male
Results contain both genders: male and female and male,female
It seems to me that gender:* search all which contains male, but not full match of value. How to do the query right?
I use it through Ruby on Rails
Product.search({
query: {
query_string: {
query: query,
default_field: "title"
}
},
size: per_page,
sort: [ _score: { order: relevance } ]
})

Is gender a keyword data type? I suspect that you left/set the default mapping to the gender field (i.e., text + keyword subfield). In this case, try the following query: dress AND gender.keyword:male

According with this I just need to put value in double quotes..
query = '(dress) AND (gender:"male")'
do not forget to escape them if needed "gender:\"male\""

Related

Rails ActiveRecord Query a field based on word contains but not partial word

I know we have LIKE option to search partial word, exact word match and also word contains (but having some problem, let me explain that below)
User.where("name like ?", "%john%")
# above code will search the name column and it will return records even if it
matches the character partially i.e "joh" also return a record.
User.where("name like ?", "john")
# above code will return a record if 'john' word is in the name column.
It will match the exact word.
User.where("name like ?", "% john %")
# this will return a record if name column contains 'john' text i.e "Sample john victor".
But if a record has "John victor" then it won't find this record because '% john %'
can only match middle of the words except first and last word in the name column
since we having space in both front and end of the word in our search i.e "% john %"
Can someone help me to find a record based on word contains in a string of one column in a Table?
You don't specify which database you're using and it's possible different databases allow different forms of matching. E.g. in postgres you could use SIMILAR TO
For a straight SQL LIKE I think you'll need to do several options ORed together.
E.g.
User.where("(name = ?) or (name like ?) or (name like ?) or (name like ?))",
'john'
'% john %',
'john %',
'% john')
That'll get values that are 'john', that inclued 'john', that start with 'john' and that end with 'john' respectively.
That might be pretty slow depending on the data you're querying but I think it'll achieve what you want.

postgresql and RoR - how quering a json type field where value is in an array

Say I have a User class with a json type address field that has keys for city and country like this: adress: {city: 'NY', country: 'USA'} and I want to get all the users that live in an array of country names like: country_names = ['Iran', 'Iraq', 'Yemen'].
How do can I do it in Ruby on Rails?
I've tried:
User.where("address->>'country' IN ?", country_names)
but I get a syntax error. what is the correct way?
The list of values of the IN clause should be enclosed by parentheses:
User.where("address->>'country' IN (?)", country_names)

Ruby on Rails search with array of values to find in multiple fields (datatables)

I implemented datatables like proposed on the http://railscasts.com/episodes/340-datatables and it works just fine. Unfortunately it doesnt concern the point of searching with spaces in the input field. If I implement it with the search function processing it with javascript it works just fine.
So what I want to do is search on the database on many fields where the parameters of the sql are splitted by space (dynamic size of parameters)
eg. "name1 street city" -> this means returned objects must contain all three "name1", "street", "city" in one of the objects fields.
Here's an example:
Person :name, :address, :city, :country
Person("Peter Mayer", "Some Street 111", "New York", "United States")
if a user searches with "Peter York" it should find the object
if a user searches with "Peter Los Angeles" it should not find anything
if a user searches with "111 Mayer States York" it should find the object
okey, i could write many different sql's respecting the amount of params but that istn't so nice
Is there an easy way to solve that?
Filtering after searching with just the first param isn't an option since pagination wouldnt work anymore
You could do the following:
Join all the attributes that must be found in one string
search_attributes = [person.name1, person.address, person.city, person.country].join(' ')
for your example search_attributes would be equal to "Peter Mayer Some Street 111 New York United States"
Then you iterate over every string in the query and make sure it is found in search_attributes using .include?, and return a record only if all strings in the sent query are found in search_attributes
I did it like this now:
searchData = params[:sSearch].split(" ")
searchString = "1 = 1"
searchParams = {}
i = 0
searchData.each do |searchParam|
searchString += " AND (persons.name like :search"+i.to_s+" or persons.address like
:search"+i.to_s+" or persons.city like :search"+i.to_s+" or persons.country like
:search"+i.to_s+"+")"
searchParams["search#{i}".to_sym] = "%"+searchParam+"%"
i += 1
end
Person.where(searchString, searchParams)

Rails returns a nil, when searching with find_by

I'm beginning to learn RoR, but i've a problem which i don't understand. With Product.find :all returns all the records from DB. But if i want to find_by_gender(1) (or even 2) it returns a nil, i'm certain that the db contains products with a gender
My code controller:
gender = params[:gender].to_i
#search_results = Product.find_by_gender(gender)
this returns a nill,
What am i doing wrong?
Greetings!
find_by_... returns either first record or nil if none found, find_all_by_... returns all records that match (or empty array if none). In your case nil means no records found with gender = 1.
Verify your data first!
Look at some sample records:
Do something like:
Product.all(:limit => 5).each {|product| product.id.to_s + product.gender}
or go into sql
sql> select id, gender from products where id < 6;
If you are to verify what the gender values are you can then create named scopes in your model for those conditions, e.g. (rails3)
(Product Model - app/models/product.rb)
scope :male where(:gender) = male_value # i.e. 1 or 'M' or 'Male' or whatever
scope :female where(:gender) = female_value # i.e. '2' or 'F' or whatever
Which will then you let write Products.male or Products.female !
Final note - should gender be in your users table? , or is this for male / female specific products?
in rails console execute
Product.pluck(:gender)
And u will know that values does it have in AR(i think true and false), so u have to use query Product.find_by_gender(true)

Compare separate columns in Mongoid

I'm looking for the mongoid equivalent to:
How to select the comparison of two columns as one column in Oracle
I can't seem to find any documentation or examples comparing columns within the same query. Is this just not possible in Mongoid?
Nope, you need to drop down to the mongodb ruby driver to do this and it will potentially be very slow as it is a javascript query that will not use an index:
Model.collection.find_one({"$where" => 'this.name == this.name2'})
Which is equivalent to third shell command here.:
> db.collection.insert({name: "awesome", name2: "awesome"})
> db.collection.insert({name: "awesome", name2: "awesome2"})
> db.collection.find('this.name == this.name2')
{ "_id" : ObjectId("xxx"), "name" : "awesome", "name2" : "awesome" }
> (line shown to signify end of results)
Note: if a document does not have key name and that same document also does not have key name2 that this will return true because null == null.

Resources