Am I using the right elasticsearch query? - ruby-on-rails

Using the elastsearch-rails gem, currently I have:
response = Employee.search(
size: 20,
query: {
multi_match: {
"query" => search_terms,
"type" => "cross_fields",
"fields" => ["first_name^3", "last_name^3", "full_name^4", "email", "job_description^5", "job_title^5"]
}
}
)
What I notice is that by doing the multi-match / cross_fields search, if I search for a term that appears only once in an Employee database column (e.g., "John" would only appear in first_name, not job_description or job_title), then I get no results back. If a term, (say a job title like "lawyer" appears in more than 1 field such as job_description and job_title), I get results back. Why is this? This seems counter-intuitive.

Related

Mongoid query hash fields with other field

Document structure -
{
"_id" : "b3bf7422-4993-4728-ae6f-98f35aa52a9c",
"feed_user_type" : "user",
"relation" : "reported_by",
"notification_title" : "Thank you for submitting the report. The moderators will now review the evidence.",
"notification_type" : {
"email" : false,
"feed" : false,
"notification" : true
},
"updated_at" : ISODate("2016-12-01T12:14:41.269Z"),
"created_at" : ISODate("2016-12-01T12:14:41.269Z")
}
Following queries works fine
Userfeed.where(:notification_type.feed => true).offset(offset).limit(size).asc(:created_at)
Userfeed.where(:feed_user_type => "user").offset(offset).limit(size).asc(:created_at)
First query is querying the field in the hash and second one is simple query querying a normal field and gives proper results.
But i combine both the queries i don't get any results at all. I tried following two syntax for combining the above query clause
userfeeds = Userfeed.where(:notification_type.feed => true,:feed_user_type => current_user.id).offset(offset).limit(size).asc(:created_at)
userfeeds = Userfeed.where(:notification_type.feed => true).where(:feed_user_type => current_user.id).offset(offset).limit(size).asc(:created_at)
How can i combine a hash field query clause with normal field query clause?
Thanks
This should work:
all_of(:'notification_type.feed' => true,:feed_user_type => current_user.id)

mongodb filtered result grouping

I have a mongo-backed contact database in rails. I am doing reports that reports multiple checkbox using a filter.
For example:
I am using checkbox filter
Table name is Conversion
Columns in Conversion table are: browser, date, city, state, country, network, language
I am selecting date, city for filter, after filtering grouping should occur, based on the filter
Note: first filter next only grouping
Sometimes: date, city, country for filter, it will depends on the user
I have done this code only
Conversion.collection.aggregate([
{ "$match" => {
"date" => { '$gte' => start_date, '$lte' => end_date }
}
},
{ "$group" => {
"_id" => {
"country" => "$country",
"city" => "$city",
"browser" => "$browser",
"network" => "$network",
"language" => "$language"
}
}
},
])
But this code is grouping all columns every time. I want the checkbox selected column only grouping to occur. For that how do I write the grouping code? Can anyone suggest any idea?

Searchkick boost exact matches

I have 15,000 courses and I would like to boost the title of each class so exact matches of a class are boosted above everything else.
When I do Course.seach_kick('theory of interest' , 1)
The correct search is returned with the course 'theory of interest' as the first result.
However, when I do Course.search_kick('theory of interest 3618', 1)
3618 being the catalog_number, no results are returned. I expected the theory of interest course to be returned, and returned first. It seems the search is looking for the complete string 'theory of interest 3618' be included in the title of the course.
I understand 'and' is the default operator, Is it a requirement that I have to use the 'or' operator? I am hesitant to use the 'or' operator because of the unexpected results.
Thanks, I really enjoy using the gem.
search method:
def self.search_kick(query, page)
search(query,
fields: ["title^10", "description", "crse_id", "subject", "catalog_number" ],
facets: [:subject],
misspellings: false,
page: page,
per_page: 20
)
end
def search_data
{
title: title,
description: description,
crse_id: crse_id,
subject: subject,
catalog_number: catalog_nbr
}
end
Why not filter catalog_number in where clause:
search(query,
fields: ["title^10", "description", "crse_id", "subject" ],
facets: [:subject],
misspellings: false,
where: {catalog_number: 3618},
page: page,
per_page: 20
)
In most cases, where clause comes from an IF:
conditions = {}
if params[:catalog_number].present?
conditions[:catalog_number] = params[:catalog_number].to_i
end
search(query,
fields: ["title^10", "description", "crse_id", "subject" ],
facets: [:subject],
misspellings: false,
where: conditions,
page: page,
per_page: 20
)
You can insert as many as possible filters into where clause, just the same as ActiveRecord.where()
docs ref: https://github.com/ankane/searchkick#queries

ruby on rails: ElasticSearch / Tire dynamic search on multiple indices

I've done a bunch of searching and I haven't been able to get an answer to this question - hopefully this isn't a repeat (apologies if it is)...
Preface: I'm using Rails & Tire to perform ElasticSearch.
I have an object, Place, with attributes "name", "city", "state", and "zip". They are indexed as follows:
indexes :name, :type => 'multi_field', :fields => {
:name => { :type => 'string', :analyzer => 'snowball' },
:"name.exact" => { :type => 'string', :index => :not_analyzed }
}
indexes :city
indexes :state
indexes :zip
There are three conditions for searching: 1. Name only, 2. (City, State OR Zip), 3. Name AND (City, State OR Zip).
My code for the "query" block is:
if (City, State).present?
boolean do
must { string "name:#{name}*" } if name.present?
must { string "city:#{city_state}*" }
must { string "state:#{city_state}*" }
end
elsif (Zip).present?
boolean do
must { string "name:#{name}*" } if name.present?
must { string "zip:#{query_parameters["zip"]}*" }
end
else
string "name:#{name}*" }
end
The aforementioned search conditions #1 and #2 work as expected against multiple tests. However, condition 3 does not - it seems to only pay attention to the "name" field. I'm assuming it has something to do with using the "city_state" variable to search on both "city" and "state"... But I'm doing this because a user can enter either "Chicago" or "Illinois" in the City, State / Zip text box and the search should still work, using either the geographic center of Chicago or the geographic center of Illinois, respectively.
Anything obvious I'm doing wrong?
However, condition 3 does not - it seems to only pay attention to the "name" field
Errr, isn't
string "name:#{name}*"
telling it to do exactly that?
or did you mean to just do
string "#{name}"

ElasticSearch and tire/Rails: use two fields for a single facet

Using Elasticsearch with Rails 3 and tire gem.
I have got facets to work on a couple of fields, but I now have a special requirement and not sure it is possible.
I have two fields on my model Project that both store the same values: Country1 and Country2
The user is allowed to store up to two countries for a project. The drop down menus on both are the same. Neither field is required.
What I would like is a single facet that 'merges' the values from Country1 and Country2 and would handle clicking on those facets intelligently (i.e. would find it whether it was in 1 or 2)
Here's my model so far: (note Country1/2 can be multiple words)
class Project < ActiveRecord::Base
mapping do
indexes :id
indexes :title, :boost => 100
indexes :subtitle
indexes :country1, :type => 'string', :index => 'not_analyzed'
indexes :country2, :type => 'string', :index => 'not_analyzed'
end
def self.search(params)
tire.search(load: true, page: params[:page], per_page: 10) do
query do
boolean do
must { string params[:query], default_operator: "AND" } if params[:query].present?
must { term :country1, params[:country] } if params[:country].present?
end
end
sort { by :display_type, "desc" }
facet "country" do
terms :country1
end
end
end
Any tips greatly appreciated!
This commit https://github.com/karmi/tire/commit/730813f in Tire brings support for aggregating over multiple fields in the "terms" facet.
The interface is:
Tire.search('articles-test') do
query { string 'foo' }
# Pass fields as an array, not string
facet('multi') { terms ['bar', 'baz'] }
end
according to the elasticsearch docs for the terms facet http://www.elasticsearch.org/guide/reference/api/search/facets/terms-facet.html this should be possible:
Multi Fields:
The term facet can be executed against more than one field, returning
the aggregation result across those fields. For example:
{
"query" : {
"match_all" : { }
},
"facets" : {
"tag" : {
"terms" : {
"fields" : ["tag1", "tag2"],
"size" : 10
}
}
}
}
did you try providing an array of fields to the term facet like terms :country1, :country2 ?
This seems to work but I need to test it more: facet('country') { terms fields: [:country1, :country2]}

Resources