返回rails中elasticsearch的特定字段

时间:2016-06-24 18:35:30

标签: ruby-on-rails elasticsearch-2.0

这似乎是一个非常简单的问题,但我从其他解决方案和网站尝试的所有内容都无效。我有三个不希望编入索引或查询的字段 - :p_s:gender:part_of_speech - 但即使我不是,我们仍然会从这些字段返回值指定它们应该被索引或查询。大约一半时,this articleno要编制索引,但它们并不表示会发生这种情况。

期限监督员:

  def search
    @terms = Term.search(params[:query]).page(params[:page])
  end

型号:

require 'elasticsearch/model'

class Term < ActiveRecord::Base

include Elasticsearch::Model
include Elasticsearch::Model::Callbacks

  settings index: { number_of_shards: 1, number_of_replicas: 0 },
    do

    mappings dynamic: 'false' do
      indexes :id, index: :not_analyzed
      indexes :name, analyzer: :spanish_analyzer
      indexes :definition, analyzer: :combined_analyzer
      indexes :etymology1, analyzer: :combined_analyzer
      indexes :etymology2, analyzer: :combined_analyzer
      indexes :uses, analyzer: :combined_analyzer
      indexes :notes1, analyzer: :combined_analyzer
      indexes :notes2, analyzer: :combined_analyzer
    end
  end

  def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['name^7', 'definition^6', 'etymology1^5', 'etymology2^4', 'uses^3', 'notes1^2', 'notes2^1'],
            operator: 'and'
          }
        }
      }
    )
  end
end

# Delete the previous term index in Elasticsearch
Term.__elasticsearch__.client.indices.delete index: Term.index_name rescue nil

# Create the new index with the new mapping
Term.__elasticsearch__.client.indices.create \
  index: Term.index_name,
  body: { settings: Term.settings.to_hash, mappings: Term.mappings.to_hash }

# Index all term records from the DB to Elasticsearch
Term.import(force: true)

2 个答案:

答案 0 :(得分:1)

要将字段标记为非索引,请使用:

mappings dynamic: 'false' do
    ...
    indexes :p_s, index: :no
    indexes :gender, index: :no
    indexes :part_of_speech, index: :no
    ...
end

默认情况下,elasticsearch会返回"_source"项下的所有文档字段。要仅获取特定字段,您可以在 热门查询 级别指定fields数组,如下所示

def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['name^7', 'definition^6', 'etymology1^5', 'etymology2^4', 'uses^3', 'notes1^2', 'notes2^1'],
            operator: 'and'
          }
        },
        fields: ['name', 'definition', 'etymology1', 'etymology2', 'uses', 'notes1', 'notes2']
      }
    )
  end

或过滤"_source"

def self.search(query)
    __elasticsearch__.search(
      {
        query: {
          multi_match: {
            query: query,
            fields: ['name^7', 'definition^6', 'etymology1^5', 'etymology2^4', 'uses^3', 'notes1^2', 'notes2^1'],
            operator: 'and'
          }
        },
        '_source': ['name', 'definition', 'etymology1', 'etymology2', 'uses', 'notes1', 'notes2']
      }
    )
end

See Elasticsearch source filtering docs for more.

使用multi_match子句时,内部fields元素指定要在您的示例中运行搜索的字段,以及可选的增强功能。外fields或&#39; _source&#39;反过来,子句确定要返回的字段,这是您之后的字段。

要在调试elasticsearch查询时更好地了解正在进行的操作,请使用Sense之类的工具。当你得到你想要的结果时,将查询转移到ruby代码可能要容易得多,反之亦然。

答案 1 :(得分:0)

我认为使用包含的elasticsearch方法很有意义。但是,在我自己的情况下,在我的模型中,我做了类似这样的事情,根据你自己的情况进行了修改:

def as_indexed_json
  as_json(only: [:id, :name, :definition, :etymology1, :etymology2, :uses, :notes1, :notes2])
end

这应该有效,因为默认情况下,Elasticsearch会调用模型中的as_indexed_json方法来获取索引所需的数据。