简体   繁体   中英

Elasticsearch sort on multiple queries

I have a query like so:

{
    "sort": [
        {
            "_geo_distance": {
                "geo": {
                    "lat": 39.802763999999996,
                    "lon": -105.08748399999999
                },
                "order": "asc",
                "unit": "mi",
                "mode": "min",
                "distance_type": "sloppy_arc"
            }
        }
    ],
    "query": {
        "bool": {
            "minimum_number_should_match": 0,
            "should": [
                {
                    "match": {
                        "name": ""
                    }
                },
                {
                    "match": {
                        "credit": true
                    }
                }
            ]
        }
    }
}

I want my search to always return ALL results, just sorted with those which have matching flags closer to the top.

I would like the sorting priority to go something like:

  1. searchTerm (name, a string)
  2. flags (credit/atm/ada/etc, boolean values)
  3. distance

How can this be achieved?

So far, the query you see above is all I've gotten. I haven't been able to figure out how to always return all results, nor how to incorporate the additional queries into the sort.

I don't believe "sort" is the answer you are looking for, actually. I believe you need a trial-and-error approach starting with a simple "bool" query where you put all your criterias (name, flags, distance). Then you give your name criteria more weight (boost) then a little bit less to your flags and even less to the distance calculation.

A "bool" "should" would be able to give you a sorted list of documents based on the _score of each and, depending on how you score each criteria, the _score is being influenced more or less.

Also, returning ALL the elements is not difficult: just add a "match_all": {} to your "bool" "should" query.

This would be a starting point, from my point of view, and, depending on your documents and your requirements (see my comment to your post about the confusion) you would need to adjust the "boost" values and test, adjust again and test again etc:

{
  "query": {
    "bool": {
      "should": [
        { "constant_score": {
            "boost": 6,
            "query": {
              "match": { "name": { "query": "something" } }
            }
        }},
        { "constant_score": {
            "boost": 3,
            "query": {
              "match": { "credit": { "query": true } }
            }
        }},
        { "constant_score": {
            "boost": 3,
            "query": {
              "match": { "atm": { "query": false } }
            }
        }},
        { "constant_score": {
            "boost": 3,
            "query": {
              "match": { "ada": {  "query": true } }
            }
        }},
        { "constant_score": {
            "query": {
              "function_score": {
                "functions": [
                  {
                    "gauss": {
                      "geo": {
                        "origin": {
                          "lat": 39.802763999999996,
                          "lon": -105.08748399999999
                        },
                        "offset": "2km",
                        "scale": "3km"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "match_all": {}
        }
      ]
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM