ruby on rails 4 - Searchkick no busca múltiples términos cuando especifica campos
ruby-on-rails-4 elasticsearch (1)
¿Alguien puede dar consejos sobre lo siguiente, por favor?
Estoy usando searchkick / elasticsearch y me gustaría buscar un término clave o términos en varios campos (nombre, fabricante). Así que, por ejemplo, si estoy buscando un producto llamado "producto mío" hecho mi "fabricante" esperaría ver este resultado si busco cualquiera de "mi producto", "algún fabricante" o "producto de algún producto" ya que ambos términos están incluidos en nombre o campos del fabricante.
Mi problema es el siguiente:
@products = Product.search query
Permite todos los términos de búsqueda enumerados anteriormente y devuelve el resultado esperado sin embargo tan pronto como agregue
@products = Product.search query, fields: [:name, :manufacturer_name]
Solo devolverá un resultado para "myproduct" o "somecompany", pero no "myproduct somecompany".
Ahora, esto no es un gran problema ya que puedo eliminar completamente la opción de campos, PERO necesito utilizar los searchkicks word_start para el campo de nombre. Entonces mi consulta final es algo como esto:
@products = Product.search query, fields: [{name: :word_start}, :manufacturer_name]
Me gustaría que los usuarios busquen la primera cadena del producto y que también puedan ingresar un fabricante, por ejemplo, "myprod somecompany". Desafortunadamente, esto arroja cero resultados cuando esperaba que devolviera el producto llamado myproduct, hecho por alguna compañía.
¿Me estoy perdiendo algo realmente obvio aquí? Puedo cambiar agregar
operator: ''or''
pero realmente quiero poder buscar en parte el nombre, agregar términos adicionales y si ambos están presentes para un registro en particular, se devuelve.
Aquí está mi código de modelo también
class Product < ActiveRecord::Base
searchkick word_start: [:name]
end
Gracias
Si todos sus campos comparten el mismo analizador, puede usar la función cross_fields
llamada cross_fields
. Si no es el caso, puede usar query_string
. Lamentablemente, searchkick
aún no admite cross_fields
y query_string
. Entonces, tienes que hacerlo tú solo.
Índice (diferentes analizadores)
searchkick merge_mappings: true, mappings: {
product: {
properties: {
name: {
type: ''string'',
analyzer: ''searchkick_word_start_index'',
copy_to: ''grouped''
},
manufacturer_name: {
type: ''string'',
analyzer: ''default_index'',
copy_to: ''grouped''
},
grouped: {
raw: {type: ''string'', index: ''not_analyzed''}
}
}
}
}
Buscar con cross_fields
@products = Product.search(body: {
query: {
multi_match: {
query: query,
type: "cross_fields",
operator: "and",
fields: [
"name",
"manufacturer_name",
"grouped",
]
}
}
}
Buscar con query_string
@products = Product.search(body: {
query: {
query_string: {
query: query,
default_operator: "AND",
fields: [
"name",
"manufacturer_name",
"grouped",
]
}
}
}
Actualización - Cambié mi respuesta al uso de diferentes analizadores y campos múltiples siguiendo esta solución .
Desafortunadamente, al pasar la consulta a searchkick
usted mismo, pierde searchkick
características de searchkick
como resaltado y conversiones, pero aún puede hacerlo agregándolo a la consulta elasticsearch
.
Agregar hightlight a la consulta
@products = Product.search(body: {
query: {
...
}, highlight: {
fields: {
name: {},
manufacturer_name: {}
}
}
Agregar conversiones a la consulta
@products = Product.search(body: {
query: {
bool: {
must: {
dis_max: {
queries: {
query_string: {
...
}
}
}
},
should: {
nested: {
path: ''conversions'',
score_mode: ''sum'',
query: {
function_score: {
boost_mode: ''replace'',
query: {
match: {
"conversions.query": query
}
},
field_value_factor: {
field: ''conversions.count''
}
}
}
}
}
}
}