【问题标题】:elastic search not found error in ruby on rails在 ruby​​ on rails 中找不到弹性搜索错误
【发布时间】:2017-12-01 07:46:04
【问题描述】:

我将在 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 引用了它

【问题讨论】:

  • DB 中似乎缺少 activerecord,但 elasticsearch 索引包含相同的文档。如果可能,请尝试重新索引整个 ES 索引...最好的解决方案是在 ES 中删除文档时在 db 中删除该文档。您可以为此使用 after_destroy 回调。为此,ES 中有一个 remove api。
  • 请问你能解释一下吗,DB中的activerecord在哪里,
  • activerecord 是 DB 中与 rails 模型表相关的每个条目。您使用 rails create 操作创建医生资料,并在保存后将数据发布到 ES。该条目是在 db 和 ES 中创建的(预计您可能已经编写了 after_commit 或 after_save)。现在您从应用程序中删除该医生资料。但是,您忘记在 ES 中删除相同的内容。也就是出现这个问题的时候。现在,当您搜索已删除的对象时,它会在 ES 中搜索并尝试从 MySQL 加载该对象。对象不存在。因此,您可能会收到此错误。
  • 你能给我一个教程来做这个吗,在这种情况下我是初学者
  • 我使用 postgresql,我是否必须更改我的 postgresql 数据库中的某些内容

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


【解决方案1】:

您的代码并没有说太多,但您的模型上似乎有一个布尔值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 }

【讨论】:

    猜你喜欢
    • 2016-05-20
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    相关资源
    最近更新 更多