Implement near match and improve prefix search

We hook the SearchGetNearMatchBefore hook to jump in before core has a chance
to do most of its near match behavior but we still let it have a chance if we
don't find anything.  This does waste some time as core duplicates our
efforts with regards to case mangling but it allows us to take advantage of
core's neat fallbacks like unquoting the search, finding user pages, and
file handling.

We also modify the prefix search behavior to build on the near match
behavior so things that would be near matches are also returned in the
prefix results.  In effect, prefix search is just a smooth lead in to near
match search.

DEPLOYMENT: This will break prefix search unless the following is run on an
Elasticsearch server before deployment to update the configuration of all
wikis:
curl -s localhost:9200/_cluster/state?pretty > state
jq '.metadata.indices | keys' < state  | tr -d  '[] ",' > indexes
while read index ; do
    curl -XPUT http://elasticsearch1:9200/$index/page/_mapping -d '{
      "page" : {
        "properties": {
          "title": {
            "type": "multi_field",
            "fields": {
              "prefix": {
                "type": "string",
                "index_analyzer": "prefix",
                "search_analyzer": "lowercase_keyword",
                "include_in_all": false
              }
            }
          }
        }
      }
    }'
done < indexes

DEPLOYMENT: After running the above prefix search will continue working
just as it does now both before and after the deployment.  An in place
reindex will improve it, however.

DEPLOYMENT: nearmatch/TitleKey reimplementation won't find any results
without an in place reindex

Bug: 58590
Bug: 58702

Change-Id: I6c249d81de5bcb617cbae209ace630d836b003cc
Merge "Implement near match and improve prefix search"