I'm using Elasticsearch as a datastore for my Ruby/Sinatra app, and I'm wanting to save images. Is there a way to index an image as a binary into ES? If so, how should I go about doing this and then converting the binary back to an image in order to display it on the site?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Elasticsearch can store binary data using the binary type. The binary type needs to be base64 encoded and will not be indexed by default. Here is an example es mapping
POST http://localhost:9200/adimages/
{
"mappings" : {
"images" : {
"properties" : {
"image" : { "type" : "binary"},
"id" : {"type" : "string"}
}
}
}
Some sinatra/ruby code
get '/pictures/:name' do |name|
@image = @es_client.search index: 'adsimages', body: { query: { match: { id: name } } }
@image = AdHelpers.get_hashie_list(@image)
content_type 'image/png' #hardcoded content type for now
fileContent = Base64.decode64(@image[0].image);
end
post '/sell/pictures' do
#adsimagesindex/images
image_id = SecureRandom.hex
file = params[:file][:tempfile] #get the post from body
fileContent = file.read
fileContent = Base64.encode64(fileContent)
@es_client.index index: 'adsimages', type: 'images', id: image_id, body: {id: image_id, image: fileContent}
redirect '/ads/sell/pictures'
end
You then use a form to submit the image
<form class="form-horizontal" action="/ads/sell/pictures" method="post">
<div class="container">
<div class="form-group">
<label for="upload-pictures">Upload Pictures</label>
<input type="file" id="file" name="upload-pictures[]" multiple>
</div>
<button type="submit" class="btn btn-default">Next</button>
</div>
</form>
to retrieve the image do 'GET /ads/sell/pictures/7a911a0355ad1cc3cfc78bbf6038699b'
If you want to store images along with the your documents (depending on your use case) you can omit the image field when doing the search by specifying the fields you want returned back. Alternatively you can just store the image id(s) with your documents and create an index only for images.
Hope this helps!