[英]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.