Elasticsearch多过滤条件查询返回空结果的问题排查及正确实现方法
Let's break down why your query isn't returning results and fix it step by step:
1. The severity.keyword field doesn't exist in your mapping
Looking at your index mapping, the severity field is defined as a text type with no keyword sub-field. When you use term: { "severity.keyword": "Critical" }, Elasticsearch is looking for a field that doesn't exist—so no matches will ever come from this condition.
2. Your time range doesn't include the sample document's timestamp
The sample document has a start_time of 1659922229000, which converts to August 7, 2022, 5:30:29 UTC. Your query uses now-1d/d to now/d, which targets the last 24 hours relative to when you run the query. Since the sample data is from 2022, this time range will never include it.
Fixes for your query
Option 1: Query the severity text field directly
Since your severity values are single words (like "Minor", "Critical"), you can use a term query directly on the severity field (the text field's analyzer will index these as single terms, so exact matches work here):
{ "query": { "bool": { "filter": [ { "term": { "severity": "Minor" } }, { "range": { "start_time": { "gte": "2022-08-06", "lte": "2022-08-08", "format": "yyyy-MM-dd" } } } ] } } }
This query will match your sample document because:
- It targets the existing
severityfield with the correct value - The time range explicitly includes the sample's
start_time
Option 2: Add a keyword sub-field for more reliable exact matches
If you want to ensure consistent exact matching (especially if severity ever has multi-word values), update your index mapping to add a keyword sub-field to severity:
PUT /historical_alerts-000035/_mapping { "properties": { "severity": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }
After updating the mapping, you'll need to reindex your existing data (since the new sub-field won't populate retroactively). Then you can use the severity.keyword field in your queries:
{ "query": { "bool": { "filter": [ { "term": { "severity.keyword": "Minor" } }, { "range": { "start_time": { "gte": 1659835200000, "lte": 1660008000000 } } } ] } } }
Key Notes
- The
bool.filterclause combines conditions with logical AND—both the severity and time range must match for a document to be returned. - Always cross-check your mapping to ensure the fields you're querying actually exist (and have the right type).
- When testing with historical data, avoid relative time ranges like
now-1d—use explicit timestamps or date ranges that cover your sample data.
内容的提问来源于stack exchange,提问作者tumpy

