Elasticsearch 6.x及以上版本替代_all查询的方案咨询
_all Field in Elasticsearch 6.x+ Alright, let's tackle this problem head-on. Since Elasticsearch 6.x deprecated the _all field and you can't rely on copy_to (because you don't know all the index fields upfront), here are the most viable alternatives to replicate that "search across all fields" behavior:
1. Use multi_match with a Wildcard for Fields
This is the closest direct replacement for _all. You can use a wildcard (*) to target all fields in the index, and adjust the match type to mirror how _all worked.
QueryBuilders.boolQuery() .should(QueryBuilders.multiMatchQuery(typeAndName.name, "*") .type(MultiMatchQueryType.CROSS_FIELDS)) // Mimics _all's merged-field behavior .should(buildMatchQuery( SearchFields.kObjectNameKey, dataModel.getLowerFieldName(PropertyType.STRING, SearchFields.kObjectNameKey), typeAndName.name));
Why this works:
- The wildcard
*tells Elasticsearch to search every field in the index. - Using
CROSS_FIELDStype treats all fields as a single combined field (just like_alldid), which is great for matching terms that might span multiple fields. - Note: If you have non-text fields in your index, they might cause unexpected results. If you can rely on a naming pattern (e.g., all text fields end with
_text), you can use*_textinstead of*to narrow it down.
2. Use query_string Query (Default All-Field Search)
The query_string query defaults to searching all eligible fields if you don't specify a fields parameter. This is another easy drop-in replacement.
QueryBuilders.boolQuery() .should(QueryBuilders.queryStringQuery(typeAndName.name)) .should(buildMatchQuery( SearchFields.kObjectNameKey, dataModel.getLowerFieldName(PropertyType.STRING, SearchFields.kObjectNameKey), typeAndName.name));
Things to watch out for:
query_stringsupports special syntax (likeAND,OR, wildcards), so if your search terms might include these characters, you'll need to escape them to avoid unexpected parsing.- It automatically skips non-searchable fields, so you don't have to worry about numeric/date fields causing errors.
3. Dynamically Fetch Index Fields (For Precision)
If you want to avoid wildcards and only search actual existing fields, you can fetch the index's mapping first, then build your multi_match query with the real field list.
// First, fetch all text fields from the index mapping (pseudo-code for the API call) List<String> allTextFields = getIndexTextFields(client, yourIndexName); // Build the query with the dynamic field list QueryBuilders.boolQuery() .should(QueryBuilders.multiMatchQuery(typeAndName.name, allTextFields.toArray(new String[0])) .type(MultiMatchQueryType.CROSS_FIELDS)) .should(buildMatchQuery( SearchFields.kObjectNameKey, dataModel.getLowerFieldName(PropertyType.STRING, SearchFields.kObjectNameKey), typeAndName.name));
Why this is useful:
- It's the most precise option—you only search fields that are actually text-based and searchable.
- The tradeoff is an extra API call to fetch the mapping, which adds a small amount of overhead. This is worth it if you need to avoid accidental matches on non-text fields.
Recommendation
If you want simplicity and close alignment with the original _all behavior, go with option 1 (multi_match with * and CROSS_FIELDS). If you need to avoid special syntax issues, option 2 (query_string) is a solid choice. For maximum precision, use option 3.
内容的提问来源于stack exchange,提问作者tuk

