在 ElasticSearch 中堆叠过滤器

Stacking filters in ElasticSearch

我正在寻找用于电子商务产品过滤的过滤器。每个对ES的请求都会至少有一个针对类别匹配的必须过滤,然后是针对属性的可选过滤。让我们说颜色和尺寸。但是,颜色和尺寸都必须与所选值之一相匹配。如果选择的颜色是蓝色和红色,则它们是 OR,但如果选择了 M 和 L 码,结果应该 return 产品是(蓝色或红色)和尺寸(M 或 L)。我的过滤器原样:

"query":{
  "filtered":{
     "filter":{
        "bool":{
           "must":[
              {
                 "term":{
                    "categories":4838
                 }
              },
              {
                 "bool":{
                    "should":[
                       {
                          "bool":{
                             "must":[
                                {
                                   "bool":{
                                      "should":[
                                         {
                                            "term":{
                                               "Colour":"White"
                                            }
                                         },
                                         {
                                            "term":{
                                               "Colour":"Black"
                                            }
                                         },
                                         {
                                            "term":{
                                               "Colour":"Blue"
                                            }
                                         }
                                      ]
                                   }
                                }
                             ]
                          }
                       },
                       {
                          "bool":{
                             "must":[
                                {
                                   "bool":{
                                      "should":[
                                         {
                                            "term":{
                                               "Size":"M"
                                            }
                                         },
                                         {
                                            "term":{
                                               "Size":"L"
                                            }
                                         }
                                      ]
                                   }
                                }
                             ]
                          }
                       }
                    ]
                 }
              }
           ]
        }
     }
  }
}

这个过滤器 returns 应该适用于所有这些。我得到所有颜色为白色、黑色或蓝色,或者尺码为 M 或 L 的产品。

总结一下它应该是怎样的:

in a single attribute it's all ORs and it expands the search, but when another attribute is selected, it becomes an AND between those attributes, but still ORs within them.

当然,属性必须在它们的 must 子句中,导致:

"query":{
  "filtered":{
     "filter":{
        "bool":{
           "must":[
              {
                 "term":{
                    "categories":4838
                 }
              },
              {
                 "bool":{
                    "should":[
                       {
                          "term":{
                             "Colour":"White"
                          }
                       },
                       {
                          "term":{
                             "Colour":"Black"
                          }
                       },
                       {
                          "term":{
                             "Colour":"Pink"
                          }
                       }
                    ]
                 }
              },
              {
                 "bool":{
                    "should":[
                       {
                          "term":{
                             "Size":"M"
                          }
                       },
                       {
                          "term":{
                             "Size":"L"
                          }
                       }
                    ]
                 }
              }
           ]
        }
     }
  }
}

除了@Mave 的回答之外,您还可以使用 Terms 过滤器而不是 Term 过滤器来简化您的搜索请求。它也使请求更具可读性。

{
   "query": {
      "filtered": {
         "filter": {
            "bool": {
               "must": [
                  {
                     "term": {
                        "categories": 4838
                     }
                  },
                  {
                     "terms": {
                        "Colour": [
                           "White",
                           "Black",
                           "Pink"
                        ]
                     }
                  },
                  {
                     "terms": {
                        "Size": [
                           "M",
                           "L"
                        ]
                     }
                  }
               ]
            }
         }
      }
   }
}