Elasticsearch文档查询与结构优化问题咨询
Hey there! Let's walk through your question step by step—covering both the query you need right now and whether a nested object structure makes sense for your use case.
1. Query for Your Current Document Structure
First, since your arr is a plain object, Elasticsearch automatically flattens its fields into arr.01, arr.02, arr.03 under the hood. To find documents where arr.02 starts with "ano" AND arr.03 is between 800-1000, you can use a bool query combining a prefix and range clause:
{ "query": { "bool": { "must": [ // Match arr.02 values starting with "ano" { "prefix": { "arr.02": "ano" } }, // Match arr.03 values in the 800-1000 range { "range": { "arr.03": { "gte": 800, "lte": 1000 } } } ] } } }
If you want more precise phrase-based prefix matching (e.g., avoiding partial-word matches), swap the prefix clause with match_phrase_prefix:
{ "match_phrase_prefix": { "arr.02": "ano" } }
This works better if arr.02 contains multi-word phrases and you want to match the start of the entire phrase.
2. Efficiency & Document Structure Optimization
Limitations of Your Current Structure
Your current plain object setup works fine for fixed keys like 01, 02, 03. But if you ever need to add many dynamic keys (e.g., 04, 05, ..., 0N), you'll run into "field explosion": Elasticsearch creates a new field for every unique key in arr, which bloats your index, slows down queries/writes, and could hit Elasticsearch's field count limits.
Is a Nested Object Right for You?
Nested objects are designed for arrays of independent objects where you need to preserve the relationship between fields in each object. This is perfect if your arr will evolve into a collection of dynamic key-value pairs (instead of a fixed set of keys).
Optimized Nested Structure Example
First, refactor your document to store arr as an array of key-value objects (split text and numeric values if needed to avoid type conflicts):
{ "arr": [ {"key": "01", "text_value": "one phrase"}, {"key": "02", "text_value": "another"}, {"key": "03", "num_value": 900} ], "field1": "val1", "field2": "val2" }
Then update your index mapping to mark arr as a nested type:
{ "mappings": { "properties": { "arr": { "type": "nested", "properties": { "key": {"type": "keyword"}, // Exact match for keys like "02" "text_value": {"type": "text", "fields": {"keyword": {"type": "keyword"}}}, // For text searches "num_value": {"type": "integer"} // For numeric range queries } }, "field1": {"type": "keyword"}, "field2": {"type": "keyword"} } } }
Corresponding Nested Query
To match both conditions in the nested structure, you'll use two nested queries wrapped in a bool.must (ensuring both conditions are met):
{ "query": { "bool": { "must": [ // Match arr entries where key is "02" and text_value starts with "ano" { "nested": { "path": "arr", "query": { "bool": { "must": [ {"term": {"arr.key": "02"}}, {"prefix": {"arr.text_value": "ano"}} ] } } } }, // Match arr entries where key is "03" and num_value is 800-1000 { "nested": { "path": "arr", "query": { "bool": { "must": [ {"term": {"arr.key": "03"}}, {"range": {"arr.num_value": {"gte": 800, "lte": 1000}}} ] } } } } ] } } }
When to Stick with Your Current Structure?
If arr will always have a fixed, small set of keys (like just 01, 02, 03), there's no need to switch to nested objects. The plain object structure is simpler and more efficient for static fields.
内容的提问来源于stack exchange,提问作者fedd

