We are using Elasticsearch version 7.3.1 and Java API.
We are implementing a "free search", which means a search for a value in ALL the fields in each segment in Elasticsearch. If that value appears in at least one of the segment's fields, it should be returned.
Until now, we have used the following: QueryBuilders.multiMatchQuery(value) and it worked well.
As for today, we have added to the mapping file some nested (Elasticsearch data type) type fields.
After that change, the code above does not return the expected results anymore.
How can I implement a search in ALL the fields in a segment without specifying each field to search?
You could implement the logic of _all of previous elasticsearch versions (this was removed after version 6 I believe).
PUT stackoverflow
{
"mappings": {
"properties": {
"all": {
"type": "text"
},
"group": {
"type": "text",
"copy_to": "all"
},
"user": {
"type": "nested",
"properties": {
"email": {
"type": "keyword",
"copy_to": "all"
},
"info": {
"type": "text",
"copy_to": "all"
}
}
}
}
}
}
Basically you add the copy_to parameter.
PUT stackoverflow/_doc/1
{
"group" : "programmers",
"user" : [
{
"email" : "[email protected]",
"info" : "java developer"
},
{
"email" : "[email protected]",
"info" : "css guru"
}
]
}
Then you can search against the all field
GET stackoverflow/_search
{
"query": {
"match": {
"all": "guru"
}
}
}
Update
Here is an example of how to modify your query in order for it to work without copy_to
GET stackoverflow/_search
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"multi_match": {
"query": "SEARCH_INPUT_HERE",
"fields": [
"group"
]
}
},
{
"nested": {
"path": "user",
"query": {
"multi_match": {
"query": "SEARCH_INPUT_HERE",
"fields": [
"user.email", "user.info"
]
}
}
}
}
]
}
}
}
Update 2
public static void main(String[] args) {
String queryInput = "QUERY_INPUT_HERE";
String[] nested = {"user", "product"};
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(queryInput, "*");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> shouldQueryBuilders = boolQueryBuilder.should();
shouldQueryBuilders.add(multiMatchQueryBuilder);
for(String path : nested) {
NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery(path, multiMatchQueryBuilder, ScoreMode.Avg);
shouldQueryBuilders.add(nestedQueryBuilder);
}
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
SearchRequest searchRequest = new SearchRequest();
searchRequest.source(searchSourceBuilder);
searchRequest.indices("MY_INDEX");
System.out.println(searchRequest.toString());
}
Output
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "QUERY_INPUT_HERE",
"fields": [
"*^1.0"
],
"type": "best_fields",
"operator": "OR",
"slop": 0,
"prefix_length": 0,
"max_expansions": 50,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1.0
}
},
{
"nested": {
"query": {
"multi_match": {
"query": "QUERY_INPUT_HERE",
"fields": [
"*^1.0"
],
"type": "best_fields",
"operator": "OR",
"slop": 0,
"prefix_length": 0,
"max_expansions": 50,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1.0
}
},
"path": "user",
"ignore_unmapped": false,
"score_mode": "avg",
"boost": 1.0
}
},
{
"nested": {
"query": {
"multi_match": {
"query": "QUERY_INPUT_HERE",
"fields": [
"*^1.0"
],
"type": "best_fields",
"operator": "OR",
"slop": 0,
"prefix_length": 0,
"max_expansions": 50,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"boost": 1.0
}
},
"path": "product",
"ignore_unmapped": false,
"score_mode": "avg",
"boost": 1.0
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With