2014-10-09 3 views
6

Отфильтрованный запрос с 3-мя фильтрами: "query": "iphone", color:5, category:10, brand:25.ElasticSearch - как исключить фильтр из агрегатов?

Как я могу получить количество продуктов в каждой торговой марке, которые имеют color:5 и category:10?

В Solr я это люблю:

fq={!tag=tag_facet_brand}facet_brand:"564"&facet.field={!ex=tag_facet_brand}facet_brand 

Как можно исключить 1 фильтр из контекста агрегации? (Я не могу использовать глобальный, потому что теряю query:iphone, я не могу использовать post_filter - из-за производительности).

+0

Вы нашли решение? –

+0

Да, через некоторое время в производстве и экспериментах решение с «глобальным»: {}, - это лучшая возможность, которую я нашел. Он работает не очень быстро, но с кешем имеет приемлемую производительность. – user3093816

+0

Связанный вопрос: http://stackoverflow.com/q/12014571/490018. –

ответ

5

Мы просто переходим от SOLR, и мы сталкиваемся с той же проблемой.

Вы можете попробовать глобальное ведро затем добавить query filter для каждого сегмента:

"filter" : { 
      "query" : { 
       "query_string" : { 
        "query" : "iPhone" 
       } 
      } 
     } 

Вы должны закончить с чем-то вроде:

{ 
    "size": 10, 
    "query": { 
     "query_string": { 
      "query": "iphone" 
     } 
    }, 
    "filter": { 
     "bool": { 
      "must": [ 
       { 
        "term": { 
         "brand": "564" 
        } 
       }, 
       { 
        "term": { 
         "color": "5" 
        } 
       }, 
       { 
        "term": { 
         "category": "10" 
        } 
       } 
      ] 
     } 
    }, 
    "aggs": { 
     "all": { 
      "global": {}, 
      "aggs": { 
       "keyword": { 
        "filter": { 
         "bool": { 
          "must": [ 
           { 
            "query": { 
             "query_string": { 
              "query": "iphone" 
             } 
            } 
           }, 
           { 
            "term": { 
             "color": "5" 
            } 
           }, 
           { 
            "term": { 
             "category": "10" 
            } 
           } 
          ] 
         } 
        }, 
        "aggs": { 
         "brand": { 
          "terms": { 
           "field": "brand" 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

«global»: {}, - это не хорошо в этом случае, потому что у меня 20 агг, поэтому размер запроса растет чрезвычайно, и он не поддерживает разработчиков. Принцип DRY должен быть также запрошен. – user3093816

+0

У нас также много aggs. Мы остаемся СУХОЙ, но в коде, генерирующем запрос ... foreach agg, вы добавляете каждый фильтр, кроме одного, связанного с agg. –

2

В дополнение к @Lionel Sengkouvanh ответ, вот равносильна java API:

SearchRequestBuilder request = client 
    .prepareSearch(INDEX_NAME) 
    .setQuery(theQuery) 
    ... 
    .addAggregation(
    AggregationBuilders.global("all").subAggregation(  
     AggregationBuilders.filter("keyword").filter(filter).subAggregation(
     AggregationBuilders.terms("brand").field("brand") 
     ) 
    ) 
); 
Смежные вопросы