Preventing and excluding certain attributes from being indexed in Elasticsearch using Rails - ruby-on-rails

I am trying to index a particular model using Ruby on Rails and Elasticsearch but even if I use index: false the email still shows up on the index? I do not want the email to be indexed, what else can I do to prevent the email attribute from being indexed?
mappings dynamic: false do
indexes :author, type: 'text'
indexes :title, type: 'text'
indexes :email, index: false
end
I then produce the index and import records using:
Book.__elasticsearch__.create_index!
followed by Book.import force: true

Related

elasticsearch-rails: Can't change data scheme

I'm using https://github.com/elastic/elasticsearch-rails,
and want to change indexes.
I changed
indexes :status, type: :keyword
to
indexes :status_id, type: :integer
and executed in rails console
Diary.__elasticsearch__.create_index! force: true
Diary.import
But the indexes in ElasticSearch did not change from status .
What do you think is wrong?

Rails elasticsearch Mappings are ignored

So I have been trying to make this work for few hours now, nothing seems to work.
I have mappings defined in my model:
settings do
mappings dynamic: false do
indexes :title, type: 'text'
indexes :description, type: 'text'
indexes :user, type: 'text' do
indexes :name, type: 'text'
end
end
end
But when I do:
Podcast.__elasticsearch__.delete_index! force: true
Podcast.__elasticsearch__.create_index! force: true
Podcast.__elasticsearch__.import force: true
and visit: http://localhost:9200/podcasts/_search?pretty=true&q=*:*&size=1000
I see all of the model data poured into the indexes(I need only title, description and user name).
What is the problem here?
When indexing, rails-ealsticsearch uses as_indexed_json. Here's my example:
def as_indexed_json(options = {})
as_json(include: {
user: {
only: [
:id,
:slug,
:name
]
}
})
end

What validations to use for an array data type

PostgreSQL adds other data types to the Active Record default.
See PostgreSQL documentation, List of available datatypes at Stackoverflow and Active Record and PostgreSQL at RailsGuides.
For the array data type it is necessary to add array: true in the migration. For instance:
create_table :books do |t|
t.string 'title'
t.string 'tags', array: true
t.integer 'ratings', array: true
end
What kind of validations should be used in the Book model?
If integer was a non-array data type I would use:
validates :ratings, numericality: { only_integer: true, greater_than: 0 }
Would this validation be correct also in case ratings is an array data type?
I am interested in validating the array elements not the array itself.
AFAIK there is no built in validation for such case.
You could write custom one:
validate :valid_ratings
private
def valid_ratings
if everything_is_ok
true
else
errors.add(:ratings, 'ratings is invalid') if something_is_wrong
end
end

How to perform ElasticSearch query on records from only a certain user (Rails Tire gem)

I have a Mongoid model which I perform ElasticSearch search queries on. Very standard:
class ActivityLog
include Mongoid::Document
include Mongoid::Timestamps
include Tire::Model::Search
include Tire::Model::Callbacks
field :extra, type: Hash
belongs_to :user, :inverse_of => :activity_logs
def self.search(params, user)
tire.search(load: true, page: params[:page], per_page: 5) do
query { string params[:query], default_operator: "AND" } if params[:query].present?
sort { by :created_at, "desc" }
end
end
I am having a hard time understanding the documentation on how to do more advanced stuff, and currently I'm stuck in how to work into my search query that search should be restricted to ActivityLog objects that belongs to the user only.
Could anyone show me how to work the user._id match requirement into the search query?
Working with ElasticSearch, there are 2 parts: mapping and search
So, if you want to search by a field of association table (users table), right. There are many ways, but this one I often use for my project:
Inside the ActivityLog model
mapping do
indexes :id, type: 'integer'
indexes :name, type: 'string', analyzer: 'snowball', boost: 5
indexes :description, type: 'string', analyzer: 'snowball'
indexes :description_latin, as: 'description.sanitize', type: 'string', analyzer: 'snowball'
indexes :user_id, as: 'user.id', type: 'string', index: :not_analyzed
indexes :user_name, as: 'user.name', type: 'string'
indexes :created_at, type: 'date'
indexes :slug, index: :not_analyzed
indexes :publish, type: 'boolean', index: :not_analyzed
end
Notify the user_id and user_name, the above definition of mapping method will map the user.id to the user_id, and user.name to user_name.
So now in search method, you can do some similar code like
filter :terms, user_id: params[:search][:user_id]
Hope this help
One correction to the above, ElasticSearch has dropped the type string and now uses text.

Indexing a MongoDB on Heroku, with Rails and Mongoid

I have a Rails app running Mongoid on Heroku and I need to set up some indexes to make the database faster. I've tried to read about it several places and I know Mongoid has some built-in functions for indexing, but I'm not sure on what to apply them and how often to index.
It is mostly my Design-model I want to index:
scope :full_member_and_show, where(full_member: true).and(show: true).desc(:created_at)
scope :not_full_member_and_show, where(full_member: false).and(show: true).desc(:created_at)
embeds_many :comments
belongs_to :designer
search_in :tags_array
attr_accessible :image, :tags, :description, :title, :featured, :project_number, :show
field :width
field :height
field :description
field :title
field :tags, type: Array
field :featured, :type => Boolean, :default => false
field :project_number, :type => Integer, :default => 0
field :show, :type => Boolean, :default => true
field :full_member, :type => Boolean, :default => false
field :first_design, :type => Boolean, :default => false
What do I need to index, how exactly do I do it with Mongoid and how often should I do it?
ERROR UPDATE
If try to index the below:
index({ full_member: 1, show: 1 }, { unique: true })
It throws me this error:
Invalid index specification {:full_member=>1, :show=>1}; should be either a string, symbol, or an array of arrays.
You don't need to index periodically: once you've added an index, mongo keeps that index up to date as the collection changes. This is the same as an index in MySQL or Postgres (you may have been thinking of something like solr)
What to index depends on what queries you'll be making against your dataset. Indexes do carry some overhead when you do updates and consume disk space so you don't want to add them when you don't need them.
You tell mongoid what indexes you want by index, for example
class Person
include Mongoid::Document
index :city
end
There are loads of examples in the mongoid docs for the various kinds of indexes mongo supports.
Then you run
rake db:mongoid:create_indexes
This determines what indexes you want (based in the calls to index in your model) and then ensures that they exist in the db, creating them if necessary. In development you'd run this after adding indexes to your models. In production it makes sense to run this as part of your deploy (you only need to if you've added indexes since the last deploy but it's way easier to just do it systematically)
There's a lot of information about how mongo uses indexes in the documentation

Resources