Random free text search from a collection from multiple fields Elastic Search Random free text search from a collection from multiple fields Elastic Search mongoose mongoose

Random free text search from a collection from multiple fields Elastic Search


If it is possible to re-create the index, then use custom _all fields for this purpose. Index time optimizations will give you better performance than search time optimizations. So you can create the mapping like:

PUT /my_index/_mapping/my_mapping{    "_all": {"enabled": false},    "properties": {        "custom_all": {            "type": "string"        },        "username": {            "copy_to": "custom_all",            "type": "string"        },        "city": {            "copy_to": "custom_all",            "type": "string"        },        "country": {            "copy_to": "custom_all",            "type": "string"        }}

Whatever fields you want to be searchable, include them in the custom_all field with copy_to param. Now you can perform searches on the custom_all field.

GET /my_index/my_mapping/_search{    "query": {        "match": {            "custom_all": "text to match"        }    }}

If you want to give higher precedence to those records where username is matching, you can use a bool query like this:

GET /my_index/my_mapping/_search{    "query": {        "bool": {            "must": {                "match": {"custom_all": "text to match"}            },            "should": [                { "match": { "username": "text to match" } }            ]        }    }}

must clause ensures that query matches the custom_all field. The should clause determines the score of the document. If the should clause matches, score will be higher. Similarly, adding more should clauses in the array will include different criteria for scoring. You can also add boost parameter to should clauses to determine which field contributes how much to the overall score. Hope this helps.


I think the closest query to what you describing is best_fields mode of the multi_match query. It will still return records with only a single word matching even if there are records with all words matching, but the records with all words will appear at the top of the list.


If you want to search a value in multiple fields then increase the number of should methods and pass more field keys. IF you want to give priority to field then replace .should by .must.

.setQuery(QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery(field1_key, value))
.should(QueryBuilders.matchQuery(field 2_key, value)) )