2011-08-25 20 views
15

He estado trabajando con ElasticSearch en los últimos meses, pero todavía me resulta complicado cuando tengo que pasar una consulta complicada.Cómo usar los parámetros ElasticSearch Query (consulta DSL) para varios tipos?

quiero para ejecutar la consulta que tendrá que buscar en los múltiples "tipos" y cada tipo tiene que ser buscado con sus propios "filtros", pero es necesario haber combinado

Por ejemplo "resultados buscado":

Necesito buscar el documento "user type" que son mis amigos y al mismo tiempo tengo que buscar el documento "tipo de objeto" que me gusta, de acuerdo con la palabra clave proporcionada.

O

La consulta que tiene tanto la "Y" y "NO" cláusula

Ejemplo consulta:

$options['query'] = array(
     'query' => array(
      'filtered' => array(
       'query' => array(
        'query_string' => array(
         'default_field' => 'name', 
         'query' => $this->search_term . '*', 
        ), 
       ), 
       'filter' => array(
        'and' => array(
         array(
          'term' => array(
           'access_id' => 2, 
          ), 
         ), 
        ), 

        'not' => array(
         array(
          'term' => array(
           'follower' => 32, 
          ), 
         ), 

         array(
          'term' => array(
           'fan' => 36, 
          ), 
         ), 
        ), 
       ), 
      ), 
     ), 
    ); 

como esta consulta está destinado a buscar el usuario con access_id = 2 , pero no debe tener el seguidor de id 32 y fan de id 36

pero esto no funciona ...

Editar: consulta modificada

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "and": [ 
      { 
      "not": { 
       "filter": { 
       "and": [ 
        { 
        "query": { 
         "query_string": { 
         "default_field": "fan", 
         "query": "*510*" 
         } 
        } 
        }, 
        { 
        "query": { 
         "query_string": { 
         "default_field": "follower", 
         "query": "*510*" 
         } 
        } 
        } 
       ] 
       } 
      } 
      }, 
      { 
      "term": { 
       "access_id": 2 
      } 
      } 
     ] 
     }, 
     "query": { 
     "field": { 
      "name": "xyz*" 
     } 
     } 
    } 
    } 
} 

ahora después de ejecutar esta consulta, que estoy recibiendo dos resultados, uno con seguidor: "34518" & ventilador: "510" y el segundo con ventilador: "34", pero no se supone que sea solo el segundo en el resultado.

¿Alguna idea?

Respuesta

14

Es posible que desee ver las diapositivas de una presentación que di este mes, lo que explica los conceptos básicos de cómo funciona el DSL consulta:

Terms of endearment - the ElasticSearch Query DSL explained

El problema de la consulta es que los filtros están anidados incorrectamente Los and y not filtros están en el mismo nivel, pero el filtro not deben estar bajo and:

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "filtered" : { 
     "filter" : { 
      "and" : [ 
       { 
        "not" : { 
        "filter" : { 
         "and" : [ 
          { 
           "term" : { 
           "fan" : 36 
           } 
          }, 
          { 
           "term" : { 
           "follower" : 32 
           } 
          } 
         ] 
        } 
        } 
       }, 
       { 
        "term" : { 
        "access_id" : 2 
        } 
       } 
      ] 
     }, 
     "query" : { 
      "field" : { 
       "name" : "keywords to search" 
      } 
     } 
     } 
    } 
} 
' 
+0

¿El filtro "no" siempre viene bajo el filtro "y", o es solo en este caso –

+0

Hola @DrTech, acabo de editar la pregunta, por favor revisa. –

+1

Su pregunta editada presenta otros problemas. Sugiero que eche un vistazo a la presentación a la que me he vinculado: explica la diferencia entre los términos y el texto, y qué tipos de consultas o filtros usar. – DrTech

3

yo sólo lo intentaron con el "BOOL"

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "term": { 
      "access_id": 2 
      } 
     }, 
     { 
      "wildcard": { 
      "name": "xyz*" 
      } 
     } 
     ], 
     "must_not": [ 
     { 
      "wildcard": { 
      "follower": "*510*" 
      } 
     }, 
     { 
      "wildcard": { 
      "fan": "*510*" 
      } 
     } 
     ] 
    } 
    } 
} 

Se da la respuesta correcta.

pero no estoy seguro de que deba usarse así?

+2

Esto funcionará, pero es terriblemente ineficiente. Las cláusulas de comodín tienen que cargar todos los términos, encontrar todos los términos que coinciden, luego reescribir la consulta para incluir todos esos términos. Eso realmente puede explotar. Es mucho mejor analizar sus datos correctamente en el momento del índice, de modo que pueda dividir sus valores en términos separados, con los que puede coincidir individualmente. Es posible que deba considerar el uso del analizador ngram, pero realmente depende de sus datos. Echa un vistazo a este hilo para ver un ejemplo http://elasticsearch-users.115913.n3.nabble.com/help-needed-with-the-query-tt3177477.html#a3178856 – DrTech

+1

Gracias @DrTech, está muy bien explicado . +1. Y realmente diría que deberías escribir un Tutorial completo en ElasticSearch, porque nadie lo ha hecho todavía :) Gracias –

Cuestiones relacionadas