ElasticSearch同字段搜索与排序异常及自定义字段支持咨询
Let's tackle your two problems step by step:
1. Why Ascending/Descending Sort Returns the Same Result
The root cause here is a mistake in your mapping configuration:
Looking at your provided mapping, you've defined fields like entity.name inside the entity object's properties. This creates a nested field path like entity.entity.name instead of the intended entity.name. When you try to sort on entity.name.sort, Elasticsearch can't find this field (it doesn't exist!) and falls back to sorting by relevance score (_score). Since all your matching documents have the same score (they all match via the entity.details field), their order is random—hence why ascending/descending gives identical results.
Fix Steps:
First, Correct Your Mapping
Update the entity object's properties to use clean field names (remove the redundant entity. prefix):
{ "entity": { "dynamic_templates": [ { "text_custom_field_template": { "match": "ltd_text_*", "mapping": { "type": "text" } } } ], "properties": { "id": { "type": "long", "index": "not_analyzed" }, "treeId": { "type": "long", "index": "not_analyzed" }, "name": { // Corrected from "entity.name" "type": "text", "fielddata": true, "fields": { "sort": { "type": "keyword", "ignore_above": 256 } } }, "url": { // Corrected from "entity.url" "type": "text" }, "details": { // Corrected from "entity.details" "type": "text" } } } }
Then, Adjust Your Query
Use the correct field path for sorting (entity.name.sort now exists with the fixed mapping):
{ "query": { "multi_match": { "query": "entity", "fields": [ "entity.details^1.0", "entity.name^4.0" ], "type": "best_fields", "operator": "AND", "slop": 0, "prefix_length": 0, "max_expansions": 50, "lenient": false, "zero_terms_query": "NONE", "boost": 1.0 } }, "sort": { "entity.name.sort": "asc" // This field now correctly maps to the keyword sort field } }
After reindexing your data with the fixed mapping, you'll get the expected sorted order: ABC → BCD → EFG → GHI → Untitled for ascending, and the reverse for descending.
2. Supporting Search & Sort for Client-Added Custom Text Fields
Your existing dynamic template matches ltd_text_* fields as text types, but it doesn't include the keyword subfield needed for sorting. Update the dynamic template to automatically add a sort keyword field to all custom text fields:
Updated Dynamic Template
{ "entity": { "dynamic_templates": [ { "text_custom_field_template": { "match": "ltd_text_*", "mapping": { "type": "text", "fields": { "sort": { "type": "keyword", "ignore_above": 256 } } } } } ], // ... keep your existing properties here } }
How to Use It
- Search: Query directly on the custom text field (e.g.,
ltd_text_description). - Sort: Use the corresponding
sortsubfield (e.g.,ltd_text_description.sort).
Example query for a custom field:
{ "query": { "match": { "ltd_text_description": "your search term" } }, "sort": { "ltd_text_description.sort": "desc" } }
Note: If you already have existing custom fields in your index, you'll need to reindex your data after updating the dynamic template to apply the new
sortsubfield to those documents.
内容的提问来源于stack exchange,提问作者Rah

