Marcel Emblazoned
Marcel Emblazoned

Reputation: 633

Using minimum_should_match in filtered elasticSearch query

I have a filtered elasticsearch query that works, but I want to use minimum_should_match to instruct ES to return only results that have at least 3 should matches. But I can't seem to figure out where to put minimum_should_match. Where should I put it?

{
  "size": 100,
  "sort": {
    "price_monthly": "asc"
  },
  "query": {
    "filtered": {
      "query": {
        "match_all": []
      },
      "filter": {
        "bool": {
          "must": [],
          "should": [
            [
              {
                "range": {
                  "mb.untouched": {
                    "gte": "0",
                    "lt": "500"
                  }
                }
              },
              {
                "range": {
                  "mb.untouched": {
                    "gte": "500",
                    "lt": "1000"
                  }
                }
              }
            ],
            [
              {
                "range": {
                  "minutes.untouched": {
                    "gte": "0",
                    "lt": "100"
                  }
                }
              },
              {
                "range": {
                  "minutes.untouched": {
                    "gte": "200",
                    "lt": "300"
                  }
                }
              }
            ],
            [
              {
                "range": {
                  "sms.untouched": {
                    "gte": "750",
                    "lt": "1000"
                  }
                }
              }
            ]
          ],
          "must_not": {
            "missing": {
              "field": "provider.untouched"
            }
          }
        }
      },
      "strategy": "query_first"
    }
  },
  "aggs": {
    "provider.untouched": {
      "terms": {
        "field": "provider.untouched"
      }
    },
    "prolong.untouched": {
      "terms": {
        "field": "prolong.untouched"
      }
    },
    "duration.untouched": {
      "terms": {
        "field": "duration.untouched"
      }
    },
    "mb.untouched": {
      "histogram": {
        "field": "mb.untouched",
        "interval": 500,
        "min_doc_count": 1
      }
    },
    "sms.untouched": {
      "histogram": {
        "field": "sms.untouched",
        "interval": 250,
        "min_doc_count": 1
      }
    },
    "minutes.untouched": {
      "histogram": {
        "field": "minutes.untouched",
        "interval": 100,
        "min_doc_count": 1
      }
    },
    "price_monthly.untouched": {
      "histogram": {
        "field": "price_monthly.untouched",
        "interval": 5,
        "min_doc_count": 1
      }
    }
  }
}

Upvotes: 9

Views: 20378

Answers (1)

Val
Val

Reputation: 217294

In order to use minimum_should_match, you need to rewrite your filtered query a little bit, i.e. you need to move your should clause to the query part of the filtered query and just keep must_not in the filter part (because missing is a filter). Then you can add minimum_should_match: 3 in the bool query part as shown below:

{
  "size": 100,
  "sort": {
    "price_monthly": "asc"
  },
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "minimum_should_match": 3,
          "must": [],
          "should": [
            [
              {
                "range": {
                  "mb.untouched": {
                    "gte": "0",
                    "lt": "500"
                  }
                }
              },
              {
                "range": {
                  "mb.untouched": {
                    "gte": "500",
                    "lt": "1000"
                  }
                }
              }
            ],
            [
              {
                "range": {
                  "minutes.untouched": {
                    "gte": "0",
                    "lt": "100"
                  }
                }
              },
              {
                "range": {
                  "minutes.untouched": {
                    "gte": "200",
                    "lt": "300"
                  }
                }
              }
            ],
            [
              {
                "range": {
                  "sms.untouched": {
                    "gte": "750",
                    "lt": "1000"
                  }
                }
              }
            ]
          ]
        }
      },
      "filter": {
        "bool": {
          "must_not": {
            "missing": {
              "field": "provider.untouched"
            }
          }
        }
      },
      "strategy": "query_first"
    }
  },
  "aggs": {
    "provider.untouched": {
      "terms": {
        "field": "provider.untouched"
      }
    },
    "prolong.untouched": {
      "terms": {
        "field": "prolong.untouched"
      }
    },
    "duration.untouched": {
      "terms": {
        "field": "duration.untouched"
      }
    },
    "mb.untouched": {
      "histogram": {
        "field": "mb.untouched",
        "interval": 500,
        "min_doc_count": 1
      }
    },
    "sms.untouched": {
      "histogram": {
        "field": "sms.untouched",
        "interval": 250,
        "min_doc_count": 1
      }
    },
    "minutes.untouched": {
      "histogram": {
        "field": "minutes.untouched",
        "interval": 100,
        "min_doc_count": 1
      }
    },
    "price_monthly.untouched": {
      "histogram": {
        "field": "price_monthly.untouched",
        "interval": 5,
        "min_doc_count": 1
      }
    }
  }
}

Upvotes: 10

Related Questions