tutorial - puertos elasticsearch
Elasticsearch ordenado por niƱos. (0)
Dos entidades: colección y producto. La colección es padre del producto.
Necesito buscar por términos de productos y mostrar colecciones con 4 productos cada uno.
Las colecciones y los productos se pueden emparejar parcialmente, pero la mejor coincidencia primero. Si el partido no está completo, algunos términos tienen prioridad.
Ejemplo: la búsqueda de "color: rojo" y "material: piedra" debe mostrar primero las piedras rojas, y luego las demás rojas (se trata de colecciones coincidentes y productos coincidentes).
Entonces, todo esto resuelto por solicitud abajo:
{
"query": {
"has_child": {
"type": "products",
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"match_all": {}
},
"boost": 1
}
},
{
"constant_score": {
"filter": {
"terms": { "_name": "colors", "colors": [5] }
},
"boost": 1.2
}
},
{
"constant_score": {
"filter": {
"terms": { "_name": "materials", "productTypes": [6] }
},
"boost": 1
}
}
]
}
},
"score_mode": "max",
"inner_hits": {
"size": 4,
"sort": [
"_score"
]
}
}
},
"sort": [
"_score"
]
}
Ok, ahora el problema.
Necesidad de ordenar por precio. Como ASC, como DESC. El precio es propiedad del producto.
Debe ordenarse por precio de productos combinados, por lo que no puede mover el precio a la colección. Necesidad de ordenar por precio como colección como productos. Colecciones ordenadas por precio mínimo (o máximo) de productos emparejados.
Debe ordenar por precio solo productos combinados al 100% (bueno, parcialmente emparejado también se puede ordenar, pero después). Quiero decir, el orden debe ser como ORDENAR _puntuación, precio
Ejemplo, que quiero obtener, ordenar por precio asc, [nn] significa producto parcialmente coincidente:
Collection1
100 - 200 - 800 - [99]
Collection2
300 - 500 - [10] - [20]
Collection3
400 - 450 - 500 - [100]
He encontrado que no se admite la clasificación por niño. Y sugerencia para recalcular el puntaje. Pero estoy usando la puntuación para ordenar por partido. Mi intento fue
{
"query": {
"has_child": {
"type": "products",
"query": {
"function_score": {
"query": {
"bool": {
"should": [
... same query as above ...
]
}
},
"functions": [
{
"script_score": {
"script": "ceil(_score * 100) * 100000 + (99999 - doc[''price''].value/100)",
"lang": "expression"
}
}
]
}
},
"score_mode": "max",
"inner_hits": {
"size": 4,
"sort": [
"_score",
{
"price": {
"order": "desc"
}
}
]
}
}
},
"sort": [
"_score"
]
}
Pero estoy realmente confundido por la puntuación de los resultados que puedo ver en respuesta. Pedir ayuda :) O, puede ser, ¿soltar y crear un índice anidado?
UPD: Encontré que estaba mal con la puntuación. Por defecto, elástica combina puntaje y resultado de script_score. Por lo tanto, el puntaje fue ceil(_score * 100) * 100000 + (99999 - doc[''price''].value/100) * _score
: se puede romper la idea, pero es fácil de corregir con el parámetro boost_mode
de function_score
. Consulta de resultados:
{
"query": {
"has_child": {
"type": "products",
"query": {
"function_score": {
"query": {
"bool": {
"should": [
... same query as above ...
]
}
},
"functions": [
{
"script_score": {
"script": "ceil((log10(_score)+10) * 100) * 100000 + (99999 - doc[''price''].value)",
"lang": "expression"
}
}
],
"boost_mode": "replace"
}
},
"score_mode": "max",
"inner_hits": {
"size": 4,
"sort": [
"_score",
{
"price": {
"order": "desc"
}
}
]
}
}
},
"sort": [
"_score"
]
}
boost_mode == ''replace
significa "usar el resultado de la función como puntaje". Además, usó log10 para estar seguro de cuántos dígitos en _score. Para ordenar por precio, los DESC deben cambiar la fórmula a ceil((log10(_score)+10) * 100) * 100000 + (doc[''price''].value)
UPD2
La fórmula ceil((log10(_score)+10) * 100) * 100000 + (99999 - doc[''price''].value)
100099952
ceil((log10(_score)+10) * 100) * 100000 + (99999 - doc[''price''].value)
devuelve 100099952
para el precio 48
y para el precio 50
(boost == 1, queryNorm == 1) porque Limitación de precisión simple.
Nueva fórmula ceil((log10(_score)+5) * 100) * 10000 + (9999 - ceil(log10(doc[''price''].value) * 1000))
- número reducido de dígitos para puntaje y cambiado de precio a lg de precio y reducido número de dígitos también. Comentarios bienvenidos.