ruby on rails 3.2 - rails - Símbolos en query-string para elasticsearch
elasticsearch model gem (1)
Puede desinfectar su cadena de consulta. Aquí hay un desinfectante que funciona para todo lo que he tratado de lanzar:
def sanitize_string_for_elasticsearch_string_query(str)
# Escape special characters
# http://lucene.apache.org/core/old_versioned_docs/versions/2_9_1/queryparsersyntax.html#Escaping Special Characters
escaped_characters = Regexp.escape(''//+-&|!(){}[]^~*?:'')
str = str.gsub(/([#{escaped_characters}])/, ''/////1'')
# AND, OR and NOT are used by lucene as logical operators. We need
# to escape them
[''AND'', ''OR'', ''NOT''].each do |word|
escaped_word = word.split('''').map {|char| "//#{char}" }.join('''')
str = str.gsub(//s*/b(#{word.upcase})/b/s*/, " #{escaped_word} ")
end
# Escape odd quotes
quote_count = str.count ''"''
str = str.gsub(/(.*)"(.*)/, ''/1/"/3'') if quote_count % 2 == 1
str
end
params[:query] = sanitize_string_for_elasticsearch_string_query(params[:query])
Tengo "documentos" (activerecords) con un atributo llamado desviaciones. El atributo tiene valores como "Bin X" "Bin $" "Bin q" "Bin%", etc.
Estoy tratando de usar tire / elasticsearch para buscar el atributo. Estoy usando el analizador de espacios en blanco para indexar el atributo de desviación. Aquí está mi código para crear los índices:
settings :analysis => {
:filter => {
:ngram_filter => {
:type => "nGram",
:min_gram => 2,
:max_gram => 255
},
:deviation_filter => {
:type => "word_delimiter",
:type_table => [''$ => ALPHA'']
}
},
:analyzer => {
:ngram_analyzer => {
:type => "custom",
:tokenizer => "standard",
:filter => ["lowercase", "ngram_filter"]
},
:deviation_analyzer => {
:type => "custom",
:tokenizer => "whitespace",
:filter => ["lowercase"]
}
}
} do
mapping do
indexes :id, :type => ''integer''
[:equipment, :step, :recipe, :details, :description].each do |attribute|
indexes attribute, :type => ''string'', :analyzer => ''ngram_analyzer''
end
indexes :deviation, :analyzer => ''whitespace''
end
end
La búsqueda parece funcionar bien cuando la cadena de consulta no contiene caracteres especiales. Por ejemplo, Bin X
devolverá solo aquellos registros que tengan las palabras Bin
AND X
en ellos. Sin embargo, buscar algo como Bin $
o Bin %
muestra todos los resultados que tienen la palabra Bin
casi ignorando el símbolo (los resultados con el símbolo aparecen más arriba en la búsqueda que resulta sin).
Aquí está el método de búsqueda que he creado
def self.search(params)
tire.search(load: true) do
query { string "#{params[:term].downcase}:#{params[:query]}", default_operator: "AND" }
size 1000
end
end
y aquí es cómo estoy construyendo el formulario de búsqueda:
<div>
<%= form_tag issues_path, :class=> "formtastic issue", method: :get do %>
<fieldset class="inputs">
<ol>
<li class="string input medium search query optional stringish inline">
<% opts = ["Description", "Detail","Deviation","Equipment","Recipe", "Step"] %>
<%= select_tag :term, options_for_select(opts, params[:term]) %>
<%= text_field_tag :query, params[:query] %>
<%= submit_tag "Search", name: nil, class: "btn" %>
</li>
</ol>
</fieldset>
<% end %>
</div>