Настраиваемое сопоставление для типа прикрепления картографа с использованием Ruby эластичного поиска
В моем проекте я храню данные в модели активной записи и индексирую HTML-документ в asticsearch с помощью плагина mapper-attachments. Мое сопоставление документов выглядит так:
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"
},
Это прекрасно работает (тип: "вложение" выше). Я могу сделать поиск через HTML док отлично.
У меня есть проблема с производительностью с activerecord, которая является mysql, и мне не нужно хранить ее в базе данных, поэтому я решил перейти на хранение в asticsearch.
Я делаю эксперимент с жемчужиной упругого поиска.
Я настраиваю отображение как ниже:
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"
},
что неправильно. Может кто-нибудь сказать мне, как сделать сопоставление с типом вложения?
Очень ценю вашу помощь.
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!
перед рукой, чтобы создать отображение для упругого поиска. Будьте осторожны, когда вы обновляете документ, вы можете получить двойную кодировку base64 поля содержимого. В моем сценарии я проверил поле оповещения.