Elasticsearch:如何针对数组首个元素执行匹配查询?
Got it, let's break down how to solve your two Elasticsearch query needs step by step. The key issue with your original query is that you weren't targeting the first element of the comps array specifically—Elasticsearch flattens array fields by default, so your original match: {city: 'york'} would match any document where any comps.city entry contains "york", not just the first one. Let's fix that:
city value of the first comps element for specified documents To get the first element's city for documents with IDs 1 and 2, use a terms query to target the specific IDs, then use _source to filter the response to only include the first comps entry's city:
{ "query": { "terms": { "id": ["1", "2"] } }, "_source": "comps.0.city" }
This will return a response like:
{ "hits": { "hits": [ { "_id": "1", "_source": { "comps": [ { "city": "Henderson" } ] } }, { "_id": "2", "_source": { "comps": [ { "city": "new york" } ] } } ] } }
Extracting the comps.0.city values from the hits will give you your expected ["Henderson", "new york"].
comps element's city field To match documents where the first comps.city contains "york", you need to explicitly target the comps.0.city field in your query. Here are two common approaches:
Option 1: Use match for token-based fuzzy matching
If your city field is analyzed (the default), the match query will handle partial matches based on tokenization (e.g., "york" will match "new york" since "york" is a token):
{ "query": { "match": { "comps.0.city": "york" } }, "_source": "comps.0.city" }
Option 2: Use wildcard for literal substring matching
If you need to match any occurrence of "york" as a substring (regardless of tokenization), use the wildcard query:
{ "query": { "wildcard": { "comps.0.city": "*york*" } }, "_source": "comps.0.city" }
Both of these queries will return only the document with ID 2, giving you the expected ["new york"].
Note for nested comps fields
If your comps field is mapped as a nested type (instead of a regular array), you'll need to wrap the query in a nested clause and use a script to ensure you're targeting the first element:
{ "query": { "nested": { "path": "comps", "query": { "bool": { "must": [ { "match": { "comps.city": "york" } }, { "script": { "script": "doc['comps.city'].indexOf(params.term) == 0", "params": { "term": "york" } } } ] } } } }, "_source": "comps.0.city" }
内容的提问来源于stack exchange,提问作者Ajay Kumar

