2012-01-18 10 views
10

Szukam zmiany z Solr na ES. Jedną z rzeczy, których nie mogę znaleźć, jest to, czy ES pozwala mi definiować filtry wykluczenia podczas faceting.Elasticsearch: wykluczanie filtrów podczas faceting możliwe? (jak w Solr)

Na przykład rozważ producttype z wartościami: A,B,C, które chcę obliczyć (tzn. Liczą się wyniki). Weź również pod uwagę, że zapytanie jest ograniczone do producttype: A.

W tym przypadku Solr pozwala mi określić, że chcę wykluczyć ograniczenie producttype: A z wpływu faceting na producttype. IOW, wyświetla liczbę zliczeń na producttype, tak jakby ograniczenie producttype: A nie zostało zastosowane.

Jak to zrobić w Solr patrz: http://wiki.apache.org/solr/SimpleFacetParameters> Tagging oraz z wyłączeniem Filtry

Czy istnieje jakiś sposób, aby to zrobić w ElasticSearch?

Odpowiedz

13

Tak, można.

Chociaż można używać filtrów w zapytaniu DSL, interfejs API wyszukiwania akceptuje również parametr najwyższego poziomu filter, który służy do filtrowania wyników wyszukiwania PO obliczeniach aspektów.

Na przykład:

1) Najpierw należy utworzyć indeks, a ponieważ chcesz product_type należy traktować jako enum, ustaw go mieć not_analyzed:

curl -XPUT 'http://127.0.0.1:9200/my_index/?pretty=1' -d ' 
{ 
    "mappings" : { 
     "product" : { 
     "properties" : { 
      "product_type" : { 
       "index" : "not_analyzed", 
       "type" : "string" 
      }, 
      "product_name" : { 
       "type" : "string" 
      } 
     } 
     } 
    } 
} 
' 

2) Indeks niektóre docs (uwaga, doc 3 ma inny product_name):

curl -XPUT 'http://127.0.0.1:9200/my_index/product/1?pretty=1' -d ' 
{ 
    "product_type" : "A", 
    "product_name" : "foo bar" 
} 
' 
curl -XPUT 'http://127.0.0.1:9200/my_index/product/2?pretty=1' -d ' 
{ 
    "product_type" : "B", 
    "product_name" : "foo bar" 
} 
' 
curl -XPUT 'http://127.0.0.1:9200/my_index/product/3?pretty=1' -d ' 
{ 
    "product_type" : "C", 
    "product_name" : "bar" 
} 
' 

3) Wykonaj wyszukiwanie produktów, których nazwa zawiera foo (co obejmuje dokument 3, a tym samym product_typeC) oblicz dla product_type aspekty wszystkich Dokumenty które foo w product_name, a następnie filtrowanie wyników wyszukiwania, product_type == A:

curl -XGET 'http://127.0.0.1:9200/my_index/product/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "text" : { 
     "product_name" : "foo" 
     } 
    }, 
    "filter" : { 
     "term" : { 
     "product_type" : "A" 
     } 
    }, 
    "facets" : { 
     "product_type" : { 
     "terms" : { 
      "field" : "product_type" 
     } 
     } 
    } 
} 
' 

# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "product_type" : "A", 
#    "product_name" : "foo bar" 
#    }, 
#    "_score" : 0.19178301, 
#    "_index" : "my_index", 
#    "_id" : "1", 
#    "_type" : "product" 
#   } 
#  ], 
#  "max_score" : 0.19178301, 
#  "total" : 1 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "facets" : { 
#  "product_type" : { 
#   "other" : 0, 
#   "terms" : [ 
#    { 
#    "count" : 1, 
#    "term" : "B" 
#    }, 
#    { 
#    "count" : 1, 
#    "term" : "A" 
#    } 
#   ], 
#   "missing" : 0, 
#   "_type" : "terms", 
#   "total" : 2 
#  } 
# }, 
# "took" : 3 
# } 

4) dokonuje wyszukiwania foo w product_name, ale kalkulacja aspekty dla wszystkich produktów w indeksie, określając parametr global:

# [Wed Jan 18 17:15:09 2012] Protocol: http, Server: 192.168.5.10:9200 
curl -XGET 'http://127.0.0.1:9200/my_index/product/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "text" : { 
     "product_name" : "foo" 
     } 
    }, 
    "filter" : { 
     "term" : { 
     "product_type" : "A" 
     } 
    }, 
    "facets" : { 
     "product_type" : { 
     "global" : 1, 
     "terms" : { 
      "field" : "product_type" 
     } 
     } 
    } 
} 
' 

# [Wed Jan 18 17:15:09 2012] Response: 
# { 
# "hits" : { 
#  "hits" : [ 
#   { 
#    "_source" : { 
#    "product_type" : "A", 
#    "product_name" : "foo bar" 
#    }, 
#    "_score" : 0.19178301, 
#    "_index" : "my_index", 
#    "_id" : "1", 
#    "_type" : "product" 
#   } 
#  ], 
#  "max_score" : 0.19178301, 
#  "total" : 1 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "facets" : { 
#  "product_type" : { 
#   "other" : 0, 
#   "terms" : [ 
#    { 
#    "count" : 1, 
#    "term" : "C" 
#    }, 
#    { 
#    "count" : 1, 
#    "term" : "B" 
#    }, 
#    { 
#    "count" : 1, 
#    "term" : "A" 
#    } 
#   ], 
#   "missing" : 0, 
#   "_type" : "terms", 
#   "total" : 3 
#  } 
# }, 
# "took" : 4 
# } 

AKTUALIZACJA ODPOWIEDZI NA ROZSZERZONE PYTANIE OD OPCJI:

Filtry można również stosować bezpośrednio do każdego aspektu - nazywane są one facet_filters.

Podobny przykład do wcześniej:

1) Tworzenie indeksu:

curl -XPUT 'http://127.0.0.1:9200/my_index/?pretty=1' -d ' 
{ 
    "mappings" : { 
     "product" : { 
     "properties" : { 
      "color" : { 
       "index" : "not_analyzed", 
       "type" : "string" 
      }, 
      "name" : { 
       "type" : "string" 
      }, 
      "type" : { 
       "index" : "not_analyzed", 
       "type" : "string" 
      } 
     } 
     } 
    } 
} 
' 

2) Główna część danych:

curl -XPUT 'http://127.0.0.1:9200/my_index/product/1?pretty=1' -d ' 
{ 
    "color" : "red", 
    "name" : "foo bar", 
    "type" : "A" 
} 
' 

curl -XPUT 'http://127.0.0.1:9200/my_index/product/2?pretty=1' -d ' 
{ 
    "color" : [ 
     "red", 
     "blue" 
    ], 
    "name" : "foo bar", 
    "type" : "B" 
} 
' 

curl -XPUT 'http://127.0.0.1:9200/my_index/product/3?pretty=1' -d ' 
{ 
    "color" : [ 
     "green", 
     "blue" 
    ], 
    "name" : "bar", 
    "type" : "C" 
} 
' 

3) wyszukiwanie, filtrowanie produktów, które mają zarówno type == A i color == blue, a następnie uruchom aspekty dla każdego atrybutu z wyłączeniem "innego" filtru:

curl -XGET 'http://127.0.0.1:9200/my_index/product/_search?pretty=1' -d ' 
{ 
    "filter" : { 
     "and" : [ 
     { 
      "term" : { 
       "color" : "blue" 
      } 
     }, 
     { 
      "term" : { 
       "type" : "A" 
      } 
     } 
     ] 
    }, 
    "facets" : { 
     "color" : { 
     "terms" : { 
      "field" : "color" 
     }, 
     "facet_filter" : { 
      "term" : { 
       "type" : "A" 
      } 
     } 
     }, 
     "type" : { 
     "terms" : { 
      "field" : "type" 
     }, 
     "facet_filter" : { 
      "term" : { 
       "color" : "blue" 
      } 
     } 
     } 
    } 
} 
' 

# [Wed Jan 18 19:58:25 2012] Response: 
# { 
# "hits" : { 
#  "hits" : [], 
#  "max_score" : null, 
#  "total" : 0 
# }, 
# "timed_out" : false, 
# "_shards" : { 
#  "failed" : 0, 
#  "successful" : 5, 
#  "total" : 5 
# }, 
# "facets" : { 
#  "color" : { 
#   "other" : 0, 
#   "terms" : [ 
#    { 
#    "count" : 1, 
#    "term" : "red" 
#    } 
#   ], 
#   "missing" : 0, 
#   "_type" : "terms", 
#   "total" : 1 
#  }, 
#  "type" : { 
#   "other" : 0, 
#   "terms" : [ 
#    { 
#    "count" : 1, 
#    "term" : "C" 
#    }, 
#    { 
#    "count" : 1, 
#    "term" : "B" 
#    } 
#   ], 
#   "missing" : 0, 
#   "_type" : "terms", 
#   "total" : 2 
#  } 
# }, 
# "took" : 3 
# } 
+0

Dzięki. W tym prostym przypadku, który działa. A jeśli mam dwie właściwości, np. 'Productcategory' i' color'. Chciałbym obliczyć dla obu właściwości i wykluczyć dowolny zestaw filtrów na właściwości, którą filtruję. Zatem faceting w 'productcategory' wyklucza wszystkie filtry' productcategory', podczas gdy faceting na 'color' wyklucza wszystkie filtry' color'. Wykonywanie aspektów globalnych nie działa w tym przypadku (jak sądzę), ponieważ chcę faceting na "productcategory" wziąć dowolne możliwe "kolorowe" filtry na koncie i na odwrót. Zdaję sobie sprawę, że jest to inne pytanie. –

+0

Rozwinąłem powyższą odpowiedź, aby pokazać, jak to zrobić. – DrTech

+0

Dobrze wiedzieć o istnieniu facet_filters. Czy rozumiem poprawnie, że określenie "facet_filters" na fasecie przesłania zestaw filtrów (globalnych)? Pomyślałbym, że muszę ustawić "global: 1" na facecie, jak również dyktować aspekt, aby zignorować globalnie ustawione filtry. –

Powiązane problemy