Tengo una estructura padre / hijo en 3 niveles. Digamos:
Empresa -> Empleado -> Disponibilidad
Dado que la disponibilidad (y también el empleado) se actualiza con frecuencia aquí, elijo usar la estructura principal / secundaria contra anidada. Y la función de búsqueda funciona bien (todos los documentos en fragmentos correctos).
Ahora quiero ordenar esos resultados. Ordenarlos por metadatos de la empresa (primer nivel) es fácil. Pero necesito ordenar también por tercer nivel (disponibilidad).
Quiero una lista de empresas ordenadas por:
- Distancia desde la ubicación dada ASC
- Calificación DESC
- Disponibilidad más pronto ASC
Por ejemplo:
La Compañía A está a 5 millas de distancia, tiene una calificación de 4 y lo más pronto posible, uno de sus empleados está disponible en 20 horas. La Compañía B también está a 5 millas de distancia, también tiene una calificación de 4, pero lo más pronto posible, uno de sus empleados está disponible en 5 horas.
Por lo tanto, el resultado de la clasificación debe ser B, A.
Me gustaría agregar un peso especial a cada uno de estos datos, así que comencé a escribir agregaciones que luego podría usar en mi script custom_score.
Lo esencial para crear índices, importar datos y buscar
Ahora, me las arreglé para escribir una consulta que en realidad devuelve el resultado, pero el depósito de agregación de disponibilidad está vacío. Sin embargo, también obtengo resultados demasiado estructurados, me gustaría aplanarlos.
Actualmente vuelvo:
ID de empresa -> ID de empleado -> primera disponibilidad
Me gustaría tener una agregación como:
IDS de la empresa -> primera disponibilidad
De esta manera puedo hacer mi custom_score
guión para calcular la puntuación y ordenarlos correctamente.
Pregunta más simplificada:
¿Cómo se puede ordenar / agregar por hijos de varios niveles (grandes) y posiblemente aplanar el resultado?
fuente
Query Failed [Failed to execute main query]]; nested: NullPointerException;
. ¿Puede ejecutar su esencia en su entorno local y asegurarse de que esté bien? ¡Gracias!Respuestas:
No necesita agregaciones para hacer esto:
Estos son los criterios de clasificación:
Si ignora el n. ° 3, puede ejecutar una consulta de empresa relativamente simple como esta:
El número 3 es complicado porque necesita buscar la disponibilidad ( empresa> empleado> disponibilidad ) para cada empresa más cercana al momento de la solicitud y utilizar esa duración como un tercer criterio de clasificación.
Usaremos una
function_score
consulta a nivel de nietos para tomar la diferencia de tiempo entre el tiempo de solicitud y cada disponibilidad en el hit_score
. (Luego usaremos_score
como tercer criterio de clasificación).Para llegar a los nietos necesitamos usar una
has_child
consulta dentro de unahas_child
consulta.Para cada empresa, queremos el Empleado disponible más pronto (y, por supuesto, su Disponibilidad más cercana). Elasticsearch 2.0 nos dará una
"score_mode": "min"
para casos como este, pero por ahora, dado que estamos limitados"score_mode": "max"
, haremos que el nieto_score
sea el recíproco de la diferencia horaria.Así que ahora el
_score
para cada nieto ( Disponibilidad ) será1 / number-of-hours-until-available
(para que podamos usar el tiempo recíproco máximo hasta que esté disponible por Empleado, y el Empleado disponible recíproco máximo (¿ly?) Por Compañía).Poniendo todo junto, seguimos consulta compañía pero el uso de empresa> empleado> Disponibilidad para generar el
_score
usar como el # 3 criterio de clasificación:fuente
_score
desde el tiempo hasta que esté disponible .Debería consultar la estructura de datos de R-Tree https://en.wikipedia.org/wiki/R-tree .
fuente