通过bool和has_child过滤弹性搜索

时间:2015-10-23 01:12:12

标签: elasticsearch

我在elasticsearch中有一个查询工作得很好:

body =
  size: opts.size
  query:          
    fuzzy_like_this:
    fields: ['title', 'content']
      like_text: opts.search
      fuzziness: 1
  filter:
    has_child:
      type: 'sku'
      filter:
        bool:
          must:
            range:
              regular_price:
                gte: opts.min_price
                lte: opts.max_price
  highlight:
    pre_tags: ['<strong>']
    post_tags: ['</strong>']
    fields:
      title:
        force_source: true
        fragment_size: 150
        number_of_fragments: 1

这会得到products,其标题或内容模糊匹配opts.searchskus具有指定的价格范围。它有效。

我现在想要另外排除products布尔设置为hide_from_catalog的任何true。然而,做出微小的改变并不像我期望的那样有效:

body =
  size: opts.size
  query:          
    fuzzy_like_this:
    fields: ['title', 'content']
      like_text: opts.search
      fuzziness: 1
  filter:
    ### Adding this causes an error ###
    bool:                        
      must_not:                  
        term:                    
          hide_from_catalog: true
    has_child:
      type: 'sku'
      filter:
        bool:
          must:
            range:
              regular_price:
                gte: opts.min_price
                lte: opts.max_price
  highlight:
    pre_tags: ['<strong>']
    post_tags: ['</strong>']
    fields:
      title:
        force_source: true
        fragment_size: 150
        number_of_fragments: 1

我已经玩了一下,似乎无法让它发挥作用。失败看起来像这样:

SearchPhaseExecutionException[Failed to execute phase [query_fetch],... 
ElasticsearchParseException[Expected field name but got START_OBJECT \"has_child\"]

我认为这是因为过滤格式不正确。

添加此额外过滤器的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

您需要在has_child子句中的bool过滤器中加入must过滤器,如下所示:

body =
  size: opts.size
  query:          
    fuzzy_like_this:
    fields: ['title', 'content']
      like_text: opts.search
      fuzziness: 1
  filter:
    bool:                        
      must_not:                  
        term:                    
          hide_from_catalog: true
      must:                  
        has_child:
          type: 'sku'
          filter:
            bool:
              must:
                range:
                  regular_price:
                    gte: opts.min_price
                    lte: opts.max_price
  highlight:
    pre_tags: ['<strong>']
    post_tags: ['</strong>']
    fields:
      title:
        force_source: true
        fragment_size: 150
        number_of_fragments: 1