簡體   English   中英

ElasticSearch將映射添加到數字,給我錯誤

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM