query net example async elasticsearch nest

async - elasticsearch.net example



Filtrar elementos cuya matriz contiene cualquiera de los valores dados (3)

Tengo un conjunto de documentos como

{ tags:[''a'',''b'',''c''] // ... a bunch properties }

Como se indica en el título: ¿Hay alguna forma de filtrar todos los documentos que contengan alguna de las etiquetas dadas usando Nest?

Por ejemplo, el registro anterior coincidiría [''c'', ''d'']

¿O debo construir múltiples "O" manualmente?


Si bien esta es una vieja pregunta, recientemente me encontré con este problema y algunas de las respuestas aquí ahora están en desuso (como señalan los comentarios). Entonces, en beneficio de otros que pueden haber tropezado aquí:

Se puede usar una consulta de term para encontrar el término exacto especificado en el índice inverso:

{ "query": { "term" : { "tags" : "a" } }

De la documentación https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

Alternativamente, puede usar una consulta de terms , que coincidirá con todos los documentos con cualquiera de los elementos especificados en la matriz dada:

{ "query": { "terms" : { "tags" : ["a", "c"]} }

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html

Hay que tener en cuenta (lo que me sorprendió): cómo define el documento también hace la diferencia. Si el campo en el que está buscando ha sido indexado como un tipo de text , Elasticsearch realizará una búsqueda de texto completo (es decir, utilizando una cadena analyzed ).

Si ha indexado el campo como una keyword se realiza una búsqueda de palabras clave utilizando una cadena ''no analizada''. Esto puede tener un impacto práctico masivo ya que las cadenas analizadas son preprocesadas (en minúsculas, puntuación eliminada, etc.) Ver ( https://www.elastic.co/guide/en/elasticsearch/guide/master/term-vs-full-text.html )

Para evitar estos problemas, el campo de cadena se ha dividido en dos tipos nuevos: texto, que debe usarse para la búsqueda de texto completo, y palabra clave, que debe usarse para la búsqueda de palabras clave. ( https://www.elastic.co/blog/strings-are-dead-long-live-strings )


También hay términos de consulta que deberían ahorrarle algo de trabajo. Aquí ejemplo de documentos:

{ "terms" : { "tags" : [ "blue", "pill" ], "minimum_should_match" : 1 } }

Debajo del capó construye debería booleano. Entonces es básicamente lo mismo que el anterior pero más corto.

También hay un filtro de términos correspondiente.

Para resumir su consulta podría verse así:

{ "filtered": { "query": { "match": { "title": "hello world" } }, "filter": { "terms": { "tags": ["c", "d"] } } } }

Con un mayor número de etiquetas, esto podría marcar una gran diferencia en la longitud.


Editar: Las cosas de bitset a continuación son quizás una lectura interesante, pero la respuesta en sí es un poco anticuada. Parte de esta funcionalidad está cambiando en 2.x. También Slawek señala en otra respuesta que la consulta de terms es una manera fácil de SECAR la búsqueda en este caso. Refactorizado al final para las mejores prácticas actuales. -Nueva Zelanda

Probablemente desee una consulta Bool (o más probablemente un Filter junto con otra consulta), con una cláusula de should .

La consulta bool tiene tres propiedades principales: must , should y must_not . Cada uno de estos acepta otra consulta o conjunto de consultas. Los nombres de las cláusulas se explican por sí mismos; en su caso, la cláusula should especificar una lista de filtros, una coincidencia con cualquiera de los cuales devolverá el documento que está buscando.

De los documentos:

En una consulta booleana sin cláusulas must , una o más cláusulas must deben coincidir con un documento. El número mínimo de cláusulas debería coincidir se puede establecer utilizando el parámetro minimum_should_match .

Aquí hay un ejemplo de cómo se vería esa consulta Bool aisladamente:

{ "bool": { "should": [ { "term": { "tag": "c" }}, { "term": { "tag": "d" }} ] } }

Y aquí hay otro ejemplo de esa consulta Bool como filtro dentro de una consulta filtrada de propósito más general:

{ "filtered": { "query": { "match": { "title": "hello world" } }, "filter": { "bool": { "should": [ { "term": { "tag": "c" }}, { "term": { "tag": "d" }} ] } } } }

Si utiliza Bool como una consulta (por ejemplo, para influir en la puntuación de las coincidencias) o como un filtro (por ejemplo, para reducir los resultados que luego se puntúan o se filtran posteriormente) es subjetivo, según sus requisitos.

En general, es preferible usar Bool a favor de un filtro Or , a menos que tenga una razón para usar And / Or / Not (tales razones existen). El blog Elasticsearch tiene más información sobre las diferentes implementaciones de cada uno, y buenos ejemplos de cuándo podría preferir Bool en lugar de And / Or / Not, y viceversa.

Blog Elasticsearch: Todo sobre conjuntos de bits de filtro Elasticsearch

Actualizar con una consulta refactorizada ...

Ahora, con todo eso fuera del camino, la consulta de terms es una versión SECA de todo lo anterior. Hace lo correcto con respecto al tipo de consulta bajo el capó, se comporta de la misma manera que bool + should usar las opciones minimum_should_match , y en general es un poco más breve.

Aquí está esa última consulta refactorizada un poco:

{ "filtered": { "query": { "match": { "title": "hello world" } }, "filter": { "terms": { "tag": [ "c", "d" ], "minimum_should_match": 1 } } } }