使用 elasticsearch-persistence ruby​​ 的映射器附件类型的自定义映射

Posted

技术标签:

【中文标题】使用 elasticsearch-persistence ruby​​ 的映射器附件类型的自定义映射【英文标题】:custom mapping for mapper attachment type with elasticsearch-persistence ruby 【发布时间】:2016-03-30 19:53:13 【问题描述】:

在我的项目中,我使用 mapper-attachments 插件将数据存储在活动记录模型中并在弹性搜索中索引 html 文档。我的文档映射如下所示:

include Elasticsearch::Model

settings index:  number_of_shards: 5  do
  mappings do
    indexes :alerted
    indexes :title, analyzer: 'english', index_options: 'offsets'
    indexes :summary, analyzer: 'english', index_options: 'offsets'
    indexes :content, type: 'attachment', fields:  
                                                    author:  index: "no",
                                                    date:  index: "no",
                                                    content:  store: "yes",
                                                               type: "string",
                                                               term_vector: "with_positions_offsets"
                                                            
                                                  
  end
end

我运行查询以仔细检查我的文档映射和结果:

    "mappings": 
          "feed_entry": 
              "properties": 
                  "content": 
                      "type": "attachment",
                      "path": "full",
                      "fields": 
                          "content": 
                              "type": "string",
                              "store": true,
                              "term_vector": "with_positions_offsets"
                          ,

效果很好(上面的 type: 'attachment')。我可以完美地通过 html doc 进行搜索。

我在使用 mysql 的 activerecord 时遇到性能问题,我真的不需要将它存储在数据库中,所以我决定迁移到存储在 elasticsearch 中。

我正在用elasticsearch-persistence gem 做一个实验。

我将映射配置如下:

include Elasticsearch::Persistence::Model
attribute :alert_id, Integer
attribute :title, String, mapping:  analyzer: 'english' 
attribute :url, String, mapping:  analyzer: 'english' 
attribute :summary, String, mapping:  analyzer: 'english' 
attribute :alerted, Boolean, default: false, mapping:  analyzer: 'english' 
attribute :fingerprint, String, mapping:  analyzer: 'english' 
attribute :feed_id, Integer
attribute :keywords

attribute :content, nil, mapping:  type: 'attachment', fields:  
                                                      author:  index: "no",
                                                      date:  index: "no",
                                                      content:  store: "yes",
                                                                 type: "string",
                                                                 term_vector: "with_positions_offsets"
                                                              
                                                    

但是当我对映射进行查询时,我得到了这样的结果:

"mappings": 
        "entry": 
            "properties": 
                "content": 
                    "properties": 
                        "_content": 
                            "type": "string"
                        ,
                        "_content_type": 
                            "type": "string"
                        ,
                        "_detect_language": 
                            "type": "boolean"
                        ,

这是错误的。谁能告诉我如何使用 attachment 类型进行映射?

非常感谢您的帮助。

【问题讨论】:

嗨,对不起,我在这个阶段没有帮助(并且远离工作环境。atm);您是否尝试过联系 gem 维护者(可能是附件)? (我允许自己在您的问题中添加链接)。我也对解决方案感兴趣;) @gfd 甚至不是解决方案,但这是个好主意。真的很感激。 【参考方案1】:

与此同时,我必须以这种方式对其进行硬编码:

  def self.recreate_index!
    mappings = 
    mappings[FeedEntry::ELASTIC_TYPE_NAME]= 

                "properties": 
                  "alerted": 
                    "type": "boolean"
                  ,
                  "title": 
                    #for exact match
                    "index": "not_analyzed",
                    "type": "string"
                  ,
                  "url": 
                    "index": "not_analyzed",
                    "type": "string"
                  ,                      
                  "summary": 
                    "analyzer": "english",
                    "index_options": "offsets",
                    "type": "string"
                  ,
                  "content": 
                    "type": "attachment",
                    "fields": 
                      "author": 
                        "index": "no"
                      ,
                      "date": 
                        "index": "no"
                      ,
                      "content": 
                        "store": "yes",
                        "type": "string",
                        "term_vector": "with_positions_offsets"
                      
                    
                  
                
          
    options = 
      index: FeedEntry::ELASTIC_INDEX_NAME,
    
    self.gateway.client.indices.delete(options) rescue nil
    self.gateway.client.indices.create(options.merge( body:  mappings: mappings))   
  end

然后重写to_hash方法

  def to_hash(options=)
    hash = self.as_json
    map_attachment(hash) if !self.alerted
    hash
  end

  # encode the content to Base64 formatj
  def map_attachment(hash)
    hash["content"] = 
      "_detect_language": false,
      "_language": "en",
      "_indexed_chars": -1 ,
      "_content_type": "text/html",
      "_content": Base64.encode64(self.content)
    
    hash
  end

那我得打电话了

FeedEntry.recreate_index! 

为弹性搜索创建映射之前。更新文档时要小心,您可能会得到 content 字段的双 base64 编码。在我的场景中,我检查了 alerted 字段。

【讨论】:

以上是关于使用 elasticsearch-persistence ruby​​ 的映射器附件类型的自定义映射的主要内容,如果未能解决你的问题,请参考以下文章

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份