在轨道上的红宝石中找不到弹性搜索错误

时间:2017-06-28 05:12:39

标签: ruby-on-rails ruby elasticsearch elasticsearch-rails

我将在DoctorProfile和Subspeciality表上进行弹性搜索。我正在处理的错误是它给出了未找到的结果。它需要医生表中的ID列表,但它不会给出希望结果,即医生和亚专科。 这就是我所做的一切: 我用过这些宝石:

gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-extensions', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'

我的搜索方法:

 def search
    query = params[:query]
    #query.encode("UTF-8")
    if query.nil?
      render json: { message: "no query is provided" }, status: :unprocessable_entity
      return
    end
    profiles = DoctorProfile.search(query).results.map { |r| r._source.id }
    subspecialties = Subspecialty.search(query).results.map { |r| r._source.title }
    subspecialties.uniq!
    profiles = profiles + DoctorProfile.where("subspeciality in (?)", subspecialties).ids
    profiles.uniq!
    logger.info "################  The profile is #{profiles} ########################"
    @doctors = DoctorProfile.find(profiles)
    @cleaned_doctors = @doctors.select { |u| !u.user.nil? }

    render json: @cleaned_doctors
  end

在医生模型中:

  after_commit on: [:create] do
    __elasticsearch__.index_document if self.enabled?
  end

  after_commit on: [:update] do
    __elasticsearch__.update_document if self.enabled?
  end

  after_commit on: [:destroy] do
    __elasticsearch__.delete_document
  end

  settings index: {
    number_of_shards: 1,
    number_of_replicas: 0,
    analysis: {
      filter: {
        autocomplete_filter: {
          type: "edge_ngram",
          min_gram: 1,
          max_gram: 20
        }
      },
      analyzer: {
        autocomplete: {
          type: "custom",
          tokenizer: "standard",
          filter: [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    }
  }

  mappings dynamic: 'false' do
    indexes :first_name, type: "string"
    indexes :last_name, type: "string"
    indexes :medical_code, type: "string"
    indexes :expertise, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
    indexes :subspeciality, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
  end

  def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['medical_code^10', 'subspeciality^5', 'expertise^2', 'first_name', 'last_name']
          }
        }
      }
    )

并且在亚专业模型中:

 after_commit on: [:create] do
    self.services = self.services.each {|str| str.force_encoding("UTF-8")}
    __elasticsearch__.index_document if self.enabled?
  end

  after_commit on: [:update] do
    self.services = self.services.each {|str| str.force_encoding("UTF-8")}
    __elasticsearch__.update_document if self.enabled?
  end

  after_commit on: [:destroy] do
    __elasticsearch__.delete_document
  end

 settings index: {
    number_of_shards: 1,
    number_of_replicas: 0,
    analysis: {
      filter: {
        autocomplete_filter: {
          type: "edge_ngram",
          min_gram: 1,
          max_gram: 20
        }
      },
      analyzer: {
        autocomplete: {
          type: "custom",
          tokenizer: "standard",
          filter: [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    }
  }

  mappings dynamic: 'false' do
    indexes :description, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
    indexes :services, type: "string"
  end

  def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['description', 'services']
          }
        }
      }
    )
  end

这是我在日志中的错误:

Couldn't find all DoctorProfiles with 'id': (031addd8-9df8-4a53-974d-da0067302ad0, ff890720-4bfb-47d8-bdb8-3dc712b27f29, 869b28e1-cdd7-4bb6-b1d0-c7296e4b0637, 6dd6a784-c54b-4bb7-a0e1-337474ec4114, 234ccc87-f0c7-42f7-b96f-cf8d85487929, 543b621d-87aa-4a34-b6d6-62144c6a387e, 77e35144-9b93-48a0-a5bb-7b3addb99dff, d368f1df-3d1a-49ce-b6f5-f791df3294b1, d3dca8de-3143-4b03-90ec-e73a27c88960, 24abb0b3-2d11-457b-b95d-972462c4a37f) (found 2 results, but was looking for 10

我改变了这行代码

@doctors = DoctorProfile.find(profiles)

@doctors = DoctorProfile.where("id in (?)",profiles)

并删除此行:

@cleaned_doctors = @ doctors.select {| u | !u.user.nil? }

现在我想知道这个方法做了什么。

@cleaned_doctors = @doctors.select { |u| !u.user.nil? }

要提一下,我有一个名为user的表,doctorProfile已经引用它

1 个答案:

答案 0 :(得分:0)

您的代码并没有多说,但似乎您的模型上有一个布尔enabled,它告诉您该记录是否要编入索引。

问题在于更新回调,因为如果您将模型从enabled更改为not enabled,而不是将其从索引中删除,则不会更新现有信息。

正确的回调是

  after_commit on: [:update] do
    if enabled?
      if previous_changes['enabled'] &&
         !previous_changes['enabled'].first
        # previously not enabled, we need to index it
        __elasticsearch__.index_document
      else
        # previously enabled, we need to update it
        __elasticsearch__.update_document
      end
    else
      # not enabled
      if previous_changes['enabled'] &&
         previous_changes['enabled'].first
        # previously enabled, delete
        __elasticsearch__.delete_document
      end
      # if it wasn't enabled before, it's not in the index anyway.
      # do nothing
    end
  end

previous_changes哈希存储保存模型时更改的属性,因此您可以检查enabled属性的先前值。见http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes

一旦你有新的回调,重建索引以在需要时删除生产中的伪造数据:

DoctorProfile.where(enabled: true).find_each { |dp| dp.__elasticsearch__.index_document }
Subspecialty.where(enabled: true).find_each { |dp| dp.__elasticsearch__.index_document }