Elasticsearch: исключение фильтров при огранке возможно?(как в Solr) - PullRequest
10 голосов
/ 18 января 2012

Я смотрю на переход от Solr к ES.Я не могу найти информацию о том, позволяет ли ES определять фильтры исключения при фасетировании.

Например, рассмотрим producttype со значениями: A,B,C, с которыми я хочу столкнуться (т. Е. Для show show count).Также учтите, что запрос ограничен producttype: A.

В этом случае Solr позволяет мне указать, что я хочу исключить ограничение producttype: A от воздействия огранки на producttype.IOW, он отображает счет на producttype, как будто ограничение producttype: A не было применено.

Как это сделать в Solr, см. http://wiki.apache.org/solr/SimpleFacetParameters> Пометка и исключение фильтров

Есть ли способ сделать это в ElasticSearch?

1 Ответ

13 голосов
/ 18 января 2012

Да, вы можете.

Хотя вы можете использовать фильтры в DSL-запросе, API-интерфейс поиска также принимает параметр filter верхнего уровня, который используется для фильтрации результатов поиска ПОСЛЕ того, как вычислены фасеты.

Например:

1) Сначала создайте свой индекс, и, поскольку вы хотите, чтобы product_type рассматривался как перечисление, установите для него значение 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) Индексируйте некоторые документы (обратите внимание, что документ 3 имеет другой 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) Выполните поиск продуктов, название которых содержит foo (исключая документ 3 и, следовательно, product_type C), рассчитать фасеты для product_type для всех документов, имеющих foo в product_name, затем отфильтровать результаты поиска по 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)Выполните поиск для foo в product_name, но рассчитайте фасеты для всех продуктов в индексе, указав параметр 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
# }

ОБНОВЛЕНИЕ, ЧТОБЫ ОТВЕТИТЬ НА РАСШИРЕННЫЙ ВОПРОС ОТОП:

Вы также можете применять фильтры непосредственно к каждому фасету - они называются facet_filters.

Пример, аналогичный предыдущему:

1) Создать индекс:

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) Индексировать некоторые данные:

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) Поиск,фильтрация по продуктам, которые имеют type == A и color == blue, затем запускает фасеты для каждого атрибута, за исключением фильтра "прочее":

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
# }
...