0

我将对 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 的表,医生Profile 引用了它

4

1 回答 1

0

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

问题在于更新回调,因为如果您将模型从 更改enablednot 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 }
于 2017-07-06T10:13:52.337 回答