[英]ElasticSearch add mapping to a numeric, gives me error
我在Rails應用程序中使用elasticsearch。 我希望我的搜索結果可以按價格排序,所以我將price屬性添加到映射中。 在此之前,我能夠成功搜索我指定的其他字段。 現在我收到這樣的錯誤:
Search#search中的Elasticsearch :: Transport :: Transport :: Errors :: BadRequest: [400] {“錯誤”:“ SearchPhaseExecutionException [無法執行階段[查詢],所有分片均失敗; shardFailures {[7aIAvW_pSlCg7HDBXwNvXA] [產品] [ 0]:SearchParseException [[產品] [0]:從[-1],大小[-1]:解析失敗[無法解析源[{\\“ query \\”:{\\“ bool \\”:{\\“應該\\“:[{\\\\ multi_match \\”:{\\“ query \\”:\\“ electronics \\”,\\“ fuzziness \\”:2,\\“ fields \\”:[\\“ name ^ 2 \\”,\\“ description \\“,\\” category.name \\“,\\” price \\“],\\” prefix_length \\“:2,\\” operator \\“:\\” and \\“}}}}}]]]]]];嵌套:NumberFormatException [對於輸入字符串:\\“ electronics \\”];}
如果我從映射中刪除了價格屬性,則會得到搜索結果,但順序不正確。 似乎結果是按第一位排序的,就像我認為的字符串一樣,例如1111似乎小於200,因為第一位的“ 1”小於“ 2”。
有任何想法嗎?
搜索控制器:
class SearchController < ApplicationController
def search
options = { sort: params[:s] }
@products = Product.search(params[:q], options).paginate(page: params[:page], per_page: 5).records
end
end
產品型號:
require "elasticsearch/model"
class Product < ActiveRecord::Base
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
def self.search(query, options={})
@search_definition = {
query: {} }
unless query.blank?
@search_definition[:query] = {
bool: {
should: [
{ multi_match: {
query: query,
fuzziness: 2,
fields: ['name^2', 'description','category.name', 'price'],
prefix_length: 2,
operator: 'and'}}]}}
else
@search_definition[:query] = { match_all: {} }
@search_definition[:sort] = [{ created_at: { order: "desc" }}]
end
if options[:sort] == 'Newest'
@search_definition[:sort] = [{ created_at: { order: "desc" }}]
@search_definition[:track_scores] = true
elsif options[:sort] == 'Price - Descending'
@search_definition[:sort] = [{ price: { order: "desc" }}]
@search_definition[:track_scores] = true
elsif options[:sort] == 'Price - Ascending'
@search_definition[:sort] = [{ price: { order: "asc" }}]
@search_definition[:track_scores] = true
end
__elasticsearch__.search @search_definition
end
settings analysis: {
analyzer: {
my_index_analyzer: {
type: "custom",
tokenizer: "standard",
filter: ["standard", "lowercase", "translation"] },
my_search_analyzer: {
type: "custom",
tokenizer: "standard",
filter: ["standard", "lowercase"] }
},
filter: {
translation: {
type: "nGram",
min_gram: 2,
max_gram: 20 }}
}
mapping do
indexes :name, type: 'string', index_analyzer: 'my_index_analyzer', search_analyzer: 'my_search_analyzer'
indexes :description, type: 'string', index_analyzer: 'my_index_analyzer', search_analyzer: 'my_search_analyzer'
indexes :created_at, type: 'date'
indexes :price, type: 'double', index: "not_analyzed"
indexes :category do
indexes :name, type: 'string', index_analyzer: 'my_index_analyzer', search_analyzer: 'my_search_analyzer'
end
end
def as_indexed_json(options={})
as_json(
only: [:name, :description, :price, :created_at],
include: { category: { only: :name } }
)
end
search.html.erb:
<div class="container main-body">
<h2>Search results</h2>
<div class="clearfix">
<ul class="list-inline pull-right">
<li><h5>Show search results by:</h5></li>
<li>
<div class="btn-group">
<button class="btn btn-default btn-md dropdown-toggle" type="button" data-toggle="dropdown">
<% sort = case
when params[:s] then params[:s]
when params[:q].blank? then 'Newest'
else 'Relevancy'
end
%>
<%= sort.humanize %> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><%= link_to "Relevancy", search_path(params.except(:controller, :action).merge(s: nil)), class: 'btn-xs' %></li>
<li><%= link_to "Newest", search_path(params.except(:controller, :action).merge(s: 'Newest')), class: 'btn-xs' %></li>
<li><%= link_to "Price - Descending", search_path(params.except(:controller, :action).merge(s: 'Price - Descending')), class: 'btn-xs' %></li>
<li><%= link_to "Price - Ascending", search_path(params.except(:controller, :action).merge(s: 'Price - Ascending')), class: 'btn-xs' %></li>
</ul>
</div></li>
</ul>
</div>
<div class="clearfix">
<%= render partial: 'products/products_form' %>
</div>
<div class="centered"><%= will_paginate @products %></div>
</div>
問題和解決方案在https://github.com/elastic/elasticsearch/issues/3975中列出
問題是multi_match查詢。 它僅適用於字符串。
編輯:
@search_definition[:query] = {
bool: {
should: [
{ multi_match: {
query: query,
fuzziness: 2,
fields: ['name^2', 'description','category.name', 'price'],
lenient: true
prefix_length: 2,
operator: 'and'}}]}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.