ruby-on-rails - ElasticSearch将映射添加到数字,给我错误

标签 ruby-on-rails elasticsearch

我在Rails应用程序中使用elasticsearch。我希望我的搜索结果可以按价格排序,所以我将price属性添加到映射中。在此之前,我能够成功搜索我指定的其他字段。现在我收到这样的错误:

Elasticsearch::Transport::Transport::Errors::BadRequest in Search#search: [400] {"error":"SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[7aIAvW_pSlCg7HDBXwNvXA][products][0]: SearchParseException[[products][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\"query\":{\"bool\":{\"should\":[{\"multi_match\":{\"query\":\"electronics\",\"fuzziness\":2,\"fields\":[\"name^2\",\"description\",\"category.name\",\"price\"],\"prefix_length\":2,\"operator\":\"and\"}}]}}}]]]; nested: NumberFormatException[For input string: \"electronics\"]; }



如果我从映射中删除了价格属性,则会得到搜索结果,但顺序不正确。似乎结果是按第一位排序的,就像我认为的字符串一样,例如1111似乎小于200,因为第一位数字“1”小于“2”。

有任何想法吗?

搜索 Controller :
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'}}]}}

关于ruby-on-rails - ElasticSearch将映射添加到数字,给我错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32839404/

相关文章:

ruby-on-rails - 我在 rails 中添加了 gem,但它仍然说 gem 丢失?

ruby-on-rails - 添加到 rails 中的多个表

ruby-on-rails - 你已经激活了 rack 1.6.0,但是你的 Gemfile 需要 rack 1.6.4

ruby-on-rails - STI 和多晶型物

php - Elasticsearch 不确定我是否需要使用 bool 查询

Elasticsearch 5.2.0放置标准化器错误

mongodb - MongoDB可以在不影响现有文档(例如Elasticsearch)的情况下进行更新

ruby-on-rails - 规范不同的数据库

elasticsearch - elasticsearch中日期直方图未排序的日期

即使没有批量索引,Elasticsearch 1.5.2 2 个节点中的高 JVM 堆