`

searchkick 和 Elasticsearch

阅读更多
基于searchkick的样例

brew install elasticsearch
brew services start elasticsearch


gem 'searchkick', '2.5.0'


class SearchObj < ApplicationRecord

  searchkick merge_mappings: true, mappings: {
    search_obj:{
      properties: {
        name: {type: 'string', analyzer: "standard"},
        cas: {type: 'string'}
      }
    }
  }

  def search_data
    {
        name: good_name,
        cas: cas
    }
  end

  # 手动调整搜索结构
  # ops: {q: '12233', type: 1}
  def self.es_search(opts)
    bools = {
      must:     [],  # a & b & c
      should:   [],  # a || b || c
      must_not: []   # !a & !b & !c
    }

    if opts[:q].present?
      bools[:should] << {
        match: {cas: { query: opts[:q], boost: 100 }}
      }

      bools[:should] << {
        match: {name: {query: opts[:q], boost: 10}}
      }

    end



    search_body = {
      query: {
        bool: bools
      },
      size: opts[:per_page] || 10,
      from: ((opts[:page] || 1) - 1) * (opts[:per_page] || 10),
      sort: "_score"
    }

    search body: search_body

  end

end


一些参考链接
https://segmentfault.com/a/1190000011490134

基于elasticsearch-rails的样例

gem 'elasticsearch-model'
gem 'elasticsearch-rails'

namespace :activities do
  task refresh_es: :environment do 
    class VendorProductPromotionPriceEs
      include ActiveModel::Model
      include Elasticsearch::Model
      index_name  "mall-#{Rails.env}"
      document_type "vendor_product_promotion_prices"
      settings index: { number_of_shards: 1, number_of_replicas: 0 } do
        mappings  do
          indexes :cas, type: 'string', index: "not_analyzed", analyzer: 'snowball'
          indexes :names, type: 'string', analyzer: 'snowball'
          indexes :names_keywords, type: 'string', analyzer: 'keyword'
          indexes :names_cn, type: 'string', analyzer: 'ik_max_word'
          indexes :names_cn_keywords, type: 'string', analyzer: 'keyword'
          indexes :status, type:  'integer'
          indexes :vendor_ids, type:  'integer'
          indexes :activity_ids, type:  'integer'
        end
      end
      attr_accessor :chemi_id, :vendor_ids, :activity_ids

      def chemical
        @_chemical ||= Chemi.find_by_id(self.chemical_id)
      end

      def id
        chemical_id
      end


      def as_indexed_json(options={})
       h = chemical.as_indexed_json(options)
       h.delete(:suggest)
       h.delete(:suggest_cn)
       h[:vendor_ids] = self.vendor_ids
       h[:activity_ids] = self.activity_ids
       h
      end
    end
    results = ActiveRecord::Base.connection.select_all 'select distinct chemical_id, vendor_id,activity_id from vendor_product_promotion_prices'
    cs = {}
    results.each do |r|
      cs[r['chemical_id']] ||= {}
      cs[r['chemical_id']]['vendor_ids'] ||= []
      cs[r['chemical_id']]['activity_ids'] ||= []
      cs[r['chemical_id']]['vendor_ids']  << r['vendor_id']
      cs[r['chemical_id']]['activity_ids'] << r['activity_id']
    end

    es = []
    cs.each do |chemical_id, values|
      es << VendorProductPromotionPriceEs.new(chemical_id: chemical_id, vendor_ids: values['vendor_ids'].to_a.uniq, activity_ids: values['activity_ids'].to_a.uniq)
    end

    index_name  = "whmall-#{Rails.env}"
    document_type = "vendor_product_promotion_prices"
    es.in_groups_of(1000,false).each do |batch|
      VendorProductPromotionPriceEs.__elasticsearch__.client.bulk( index:   index_name, type:    document_type, body:    batch.map { |model| { index: { _id: model.id, data: model.as_indexed_json}}})
    end
  end
end


rake environment elasticsearch:import:model FORCE=y CLASS='Chemi' SCOPE='with_products'

更新产品在elasticsearch中的索引
chem = Chem.find(19385)
chem.__elasticsearch__.index_document(refresh: true) # index_document是创建索引, refresh: true 是强制ES刷新索引,刷新后才能search
# #需要注意,chem.danger 需要设置为0,不能是nil

获取产品在ES里的索引信息
chem.__elasticsearch__.as_indexed_json

删除产品在ES中的索引
chem.__elasticsearch__.delete_document(refresh: true)

重建所有的产品索引
Chemical.__elasticsearch__.reindex!


一些参考链接
https://www.rubydoc.info/gems/elasticsearch-api/

分词:
Elasticsearch 标准分词和ik分词的差别
https://blog.csdn.net/silent1/article/details/44590701

ElasticSearch最全分词器比较及使用方法 - 赵英超的博客 - CSDN博客: https://blog.csdn.net/ZYC88888/article/details/83620572


另外的一些gem
sunspot/sunspot
https://blog.csdn.net/raosheng1993/article/details/45438573
https://ruby-china.org/topics/21473

搜索引擎选择: Elasticsearch与Solr
https://www.cnblogs.com/chowmin/articles/4629220.html
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics