Tire Gem возвращает «Не удается отсортировать строковые типы с более чем одним значением в документе или более чем с одним токеном в поле»

Я сопоставил связанное поле как мультиполе. Я установил свойство «имя» для анализа с помощью анализатора снежного кома и «точное» как не анализируемое. Я также могу искать в этом поле и фильтровать. Я не могу сортировать по этому полю. При попытке сортировки эластичный возвращает ошибку «Не удается отсортировать строковые типы с более чем одним значением на документ или более чем с одним токеном на поле».

Я попытался создать дополнительное поле под названием «сырой», похожее на точное, и это тоже не сработало. Ниже приведено мое сопоставление и то, как я пытаюсь выполнить сортировку с помощью драгоценного камня шины:

    mapping do
    indexes :sectors, :type => 'object',
      :properties => { :name => { :type => 'multi_field',
                                  :fields => {
                                    :name =>  { :type => 'string', :analyzer => 'snowball' },
                                    :exact => { :type => 'string', :index => 'not_analyzed' , :include_in_all => false }
                                  }
                                  }
                       }
end

def to_indexed_json
    to_json( :include => {
               ...
               :sectors => { :only => ["name"] },
               ...
    })
end

def self.search(params)
  tire.search(:load => true, :page=>params[:page], :per_page => 12) do

    if params[:query].present?
      query { string params[:query], :default_operator => "OR" }
    else
      query { all }
    end

    filter :term, "sectors.name.exact" => params[:sector] if params[:sector].present?
    sort { by 'sectors.name.exact','asc' } if !params[:sort][:sector].blank?
  end
end

person Macho Geek    schedule 14.10.2012    source источник


Ответы (3)


В основном есть две причины, по которым вы получаете эту ошибку:

  • У вас есть более одного значения для каждого поля: ваше поле анализируется, и токенизатор создает несколько токенов из своего содержимого, что не относится к вашему полю name.exact, поскольку оно not_analyzed в вашем отображении.
  • У вас более одного значения в документе: вы добавляете несколько значений в поле name, например, предоставляете массив значений при индексировании.

Я бы проверил, как выглядят ваши документы. Чтобы сделать это быстро, вы можете создать фасет условий на основе сценария, который возвращает количество элементов, включенных в поле name.exact, как показано ниже. Если вы возвращаете хотя бы одну из записей фасета с термином больше 1, это означает, что вы добавили несколько значений в поле хотя бы один раз, поэтому вы не можете сортировать по нему.

{
    "query" : {
        "match_all" : {}
    },
    "facets" : {
        "my_facet" : {
            "terms" : {
                "script_field" : "doc['name.exact'].values.length"
            }
        }
    }
}
person javanna    schedule 14.10.2012
comment
Я выполнил следующее: curl -X GET localhost:9200/myprj/prj/_search ?load=true&pretty=true -d '{запрос:{match_all:{}},фасеты:{сортировщики:{термины:{script_field:doc['sectors.name.exact'].values.length} }}}' - person Macho Geek; 14.10.2012
comment
Похоже, у вас есть 1 документ с 3 терминами и 1 с 2 терминами. Спасибо, Джаванна, за подсказку со сценарием! Очень интересно! - person dadoonet; 15.10.2012
comment
@MachoGeek Я имел в виду значение больше 1. 399 ваших документов имеют 1 значение для этого поля, один имеет 2 значения, один имеет 3, 13 документов вообще не имеют значения. Чтобы отсортировать по нему, вам нужно иметь значение 0 или 1. - person javanna; 15.10.2012
comment
@javaanna, звучит хорошо, я продолжу копать. Я думаю, у меня есть немного лучшее представление о том, что искать сейчас. - person Macho Geek; 15.10.2012
comment
Рад знать! Возможно, вы захотите принять один из наших ответов. - person javanna; 15.10.2012
comment
Сортировка работает, но пропускает 9 совпадений из результатов. Я понимаю, что это проблема с тем, как данные индексируются. - person Macho Geek; 16.10.2012

ИМХО, должно работать. Просто интересно, применяется ли ваше сопоставление. Можете ли вы проверить это с помощью команды curl?

Что-то типа:

$ curl -XGET 'http://localhost:9200/twitter/tweet/_mapping'

person dadoonet    schedule 14.10.2012
comment
Да, он возвращает: секторы: {свойства: {имя: {тип: multi_field, поля: {имя: {тип: строка, анализатор: снежный ком}, точный: {тип: строка, индекс: не_анализируется, включает_в_все: ложь}, необработанный: {тип: строка, индекс: не проанализировано, хранить: да, включить_в_все: ложь}}}} - person Macho Geek; 14.10.2012

У меня такая же проблема. Я обновил свой elasticsearch, и это решило проблему.

brew update
brew upgrade elasticsearch

и по инструкции:

Чтобы перезагрузить elasticsearch после обновления:

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.elasticsearch.plist
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.elasticsearch.plist
person Someone Else    schedule 23.09.2013