Skip to content

Commit cd31ba4

Browse files
Add version field type (#11461)
* Add version field type Signed-off-by: Fanit Kolchina <[email protected]> * Apply suggestions from code review Signed-off-by: Nathan Bower <[email protected]> --------- Signed-off-by: Fanit Kolchina <[email protected]> Signed-off-by: Nathan Bower <[email protected]> Co-authored-by: Nathan Bower <[email protected]> (cherry picked from commit 0161840) Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 651f62c commit cd31ba4

File tree

2 files changed

+308
-0
lines changed

2 files changed

+308
-0
lines changed

_mappings/supported-field-types/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ You can specify data types for your fields when creating a mapping. The followin
3131
| [`wildcard`]({{site.url}}{{site.baseurl}}/mappings/supported-field-types/wildcard/) | Enables efficient substring and regex matching. |
3232
| [`token_count`]({{site.url}}{{site.baseurl}}/mappings/supported-field-types/token-count/) | Stores the number of tokens after analysis. |
3333
| [`constant_keyword`]({{site.url}}{{site.baseurl}}/mappings/supported-field-types/constant-keyword/) | Uses the same value for all documents in the index. |
34+
| [`version`]({{site.url}}{{site.baseurl}}/mappings/supported-field-types/version/) | A semantic version string that follows a semantic versioning specification. |
3435

3536
## Numeric field types
3637

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
---
2+
layout: default
3+
title: Version
4+
parent: Supported field types
5+
nav_order: 75
6+
redirect_from:
7+
- /opensearch/supported-field-types/version/
8+
- /field-types/supported-field-types/version/
9+
---
10+
11+
# Version field type
12+
**Introduced 3.2**
13+
{: .label .label-purple }
14+
15+
The `version` field type is designed for indexing and querying version strings that follow [Semantic Versioning (SemVer)](https://semver.org/) specifications. This field type enables proper ordering and comparison of version strings such as `1.0.0`, `2.1.0-alpha`, `1.3.0+build.1`, and others.
16+
17+
The `version` field type provides the following functionality:
18+
19+
- Correctly parses semantic version strings with major, minor, and patch components
20+
- Handles pre-release identifiers like `-alpha`, `-beta`, and `-rc.1`
21+
- Accepts build metadata like `+build.123` but ignores it for ordering (per SemVer specification)
22+
- Versions are sorted according to semantic versioning rules (for example, `1.0.0-alpha < 1.0.0-beta < 1.0.0`)
23+
- Compatible with various query types, including range, term, terms, wildcard, prefix, and more
24+
25+
## Version format
26+
27+
Version strings must follow the semantic versioning format:
28+
29+
```
30+
<major>.<minor>.<patch>[-<pre-release>][+<build-metadata>]
31+
```
32+
33+
The variables in the preceding format must be provided as follows.
34+
35+
| Component | Required/Optional | Description | Example |
36+
|:----------|:------------------|:------------|:--------|
37+
| `major`, `minor`, `patch` | Required | Non-negative integers representing the core version number | `1.2.3` |
38+
| `pre-release` | Optional | Alphanumeric identifiers separated by dots, indicating a pre-release version | `-alpha`, `-beta.1`, `-rc.2` |
39+
| `build-metadata` | Optional | Alphanumeric identifiers separated by dots, providing build information (ignored for ordering) | `+build.123`, `+20230815` |
40+
41+
## Example mapping
42+
43+
Create an index with a version field:
44+
45+
```json
46+
PUT test_versions
47+
{
48+
"mappings": {
49+
"properties": {
50+
"app": {
51+
"type": "keyword"
52+
},
53+
"version": {
54+
"type": "version"
55+
},
56+
"release_date": {
57+
"type": "date"
58+
},
59+
"description": {
60+
"type": "text"
61+
}
62+
}
63+
}
64+
}
65+
```
66+
{% include copy-curl.html %}
67+
68+
69+
## Indexing version data
70+
71+
Index documents with version fields:
72+
73+
```json
74+
POST test_versions/_bulk
75+
{ "index": {} }
76+
{ "app": "AlphaApp", "version": "1.0.0", "release_date": "2023-01-01", "description": "Initial release" }
77+
{ "index": {} }
78+
{ "app": "AlphaApp", "version": "1.0.1", "release_date": "2023-02-15", "description": "Bug fix release" }
79+
{ "index": {} }
80+
{ "app": "AlphaApp", "version": "1.1.0", "release_date": "2023-05-10", "description": "Minor feature update" }
81+
{ "index": {} }
82+
{ "app": "AlphaApp", "version": "2.0.0", "release_date": "2024-01-01", "description": "Major release" }
83+
{ "index": {} }
84+
{ "app": "BetaApp", "version": "0.9.0", "release_date": "2022-12-01", "description": "Beta release" }
85+
{ "index": {} }
86+
{ "app": "BetaApp", "version": "1.0.0-alpha", "release_date": "2023-03-01", "description": "Alpha pre-release" }
87+
{ "index": {} }
88+
{ "app": "BetaApp", "version": "1.0.0-alpha.1", "release_date": "2023-03-10", "description": "Alpha patch" }
89+
{ "index": {} }
90+
{ "app": "BetaApp", "version": "1.0.0-beta", "release_date": "2023-04-01", "description": "Beta pre-release" }
91+
{ "index": {} }
92+
{ "app": "BetaApp", "version": "1.0.0-rc.1", "release_date": "2023-04-15", "description": "Release candidate" }
93+
{ "index": {} }
94+
{ "app": "BetaApp", "version": "1.0.0+20230815", "release_date": "2023-08-15", "description": "Build metadata release" }
95+
```
96+
{% include copy-curl.html %}
97+
98+
## Querying version fields
99+
100+
The version field type supports various query types.
101+
102+
### Term query
103+
104+
Find documents with a specific version:
105+
106+
```json
107+
GET test_versions/_search
108+
{
109+
"query": {
110+
"term": { "version": "1.0.1" }
111+
}
112+
}
113+
```
114+
{% include copy-curl.html %}
115+
116+
#### Response
117+
118+
```json
119+
{
120+
"took": 5,
121+
"timed_out": false,
122+
"_shards": {
123+
"total": 1,
124+
"successful": 1,
125+
"skipped": 0,
126+
"failed": 0
127+
},
128+
"hits": {
129+
"total": {
130+
"value": 1,
131+
"relation": "eq"
132+
},
133+
"max_score": 1.0466295,
134+
"hits": [
135+
{
136+
"_index": "test_versions",
137+
"_id": "cSWNQpcBY7cEASBv3Vr1",
138+
"_score": 1.0466295,
139+
"_source": {
140+
"app": "AlphaApp",
141+
"version": "1.0.1",
142+
"release_date": "2023-02-15",
143+
"description": "Bug fix release"
144+
}
145+
}
146+
]
147+
}
148+
}
149+
```
150+
151+
### Range query
152+
153+
Find versions within a specific range:
154+
155+
```json
156+
GET test_versions/_search
157+
{
158+
"query": {
159+
"range": {
160+
"version": { "gte": "2.0.0" }
161+
}
162+
}
163+
}
164+
```
165+
{% include copy-curl.html %}
166+
167+
#### Response
168+
169+
```json
170+
{
171+
"took": 3,
172+
"timed_out": false,
173+
"_shards": {
174+
"total": 1,
175+
"successful": 1,
176+
"skipped": 0,
177+
"failed": 0
178+
},
179+
"hits": {
180+
"total": {
181+
"value": 1,
182+
"relation": "eq"
183+
},
184+
"max_score": 1,
185+
"hits": [
186+
{
187+
"_index": "test_versions",
188+
"_id": "cyWNQpcBY7cEASBv3Vr1",
189+
"_score": 1,
190+
"_source": {
191+
"app": "AlphaApp",
192+
"version": "2.0.0",
193+
"release_date": "2024-01-01",
194+
"description": "Major release"
195+
}
196+
}
197+
]
198+
}
199+
}
200+
```
201+
202+
### Terms query
203+
204+
Find documents matching multiple specific versions:
205+
206+
```json
207+
GET test_versions/_search
208+
{
209+
"query": {
210+
"terms": {
211+
"version": ["1.0.0", "1.0.0-alpha"]
212+
}
213+
}
214+
}
215+
```
216+
{% include copy-curl.html %}
217+
218+
### Wildcard query
219+
220+
Find versions matching a pattern:
221+
222+
```json
223+
GET test_versions/_search
224+
{
225+
"query": {
226+
"wildcard": {
227+
"version": "1.2.0-*"
228+
}
229+
}
230+
}
231+
```
232+
{% include copy-curl.html %}
233+
234+
### Prefix query
235+
236+
Find versions with a specific prefix:
237+
238+
```json
239+
GET test_versions/_search
240+
{
241+
"query": {
242+
"prefix": {
243+
"version": {
244+
"value": "1.0.0-"
245+
}
246+
}
247+
}
248+
}
249+
```
250+
{% include copy-curl.html %}
251+
252+
## Sorting by version
253+
254+
To sort by version, provide the `sort` parameter in the request. Versions are sorted according to semantic versioning rules:
255+
256+
```json
257+
GET test_versions/_search
258+
{
259+
"query": { "match_all": {} },
260+
"sort": [
261+
{ "version": { "order": "asc" } }
262+
]
263+
}
264+
```
265+
{% include copy-curl.html %}
266+
267+
This request returns documents sorted in version order, with pre-release versions appearing before their corresponding stable versions: `0.9.0`, `1.0.0-alpha`, `1.0.0-alpha.1`, `1.0.0-beta`, `1.0.0-rc.1`, `1.0.0+20230815`, `1.0.1`, `1.1.0`, `2.0.0`.
268+
269+
## Version comparison rules
270+
271+
The version field follows semantic versioning comparison rules:
272+
273+
1. `major`, `minor`, `patch`: Compared numerically (`1.2.3` < `1.2.4` < `1.3.0` < `2.0.0`).
274+
2. Pre-release precedence: Pre-release versions have lower precedence than normal versions (`1.0.0-alpha` < `1.0.0`).
275+
3. Pre-release comparison: When both versions are pre-releases, they are compared lexically by each dot-separated identifier (`1.0.0-alpha` < `1.0.0-alpha.1` < `1.0.0-beta`).
276+
4. Build metadata ignored: Build metadata does not affect version precedence (`1.0.0+build.1` equals `1.0.0+build.2` for sorting purposes).
277+
278+
## Parameters
279+
280+
The version field type accepts the following optional parameters.
281+
282+
Parameter | Description
283+
:--- | :---
284+
`null_value` | A value to be substituted for any explicit `null` values. Must be a valid version string. Defaults to `null`, which means `null` fields are treated as missing.
285+
286+
### Example with null_value
287+
288+
```json
289+
PUT software_with_nulls
290+
{
291+
"mappings": {
292+
"properties": {
293+
"version": {
294+
"type": "version",
295+
"null_value": "0.0.0"
296+
}
297+
}
298+
}
299+
}
300+
```
301+
{% include copy-curl.html %}
302+
303+
## Limitations
304+
305+
- Version strings must follow the semantic versioning format. Invalid version strings will cause indexing to fail.
306+
- Build metadata is accepted but ignored during comparisons and sorting.
307+
- The field does not support advanced version range specifications like `^1.2.3` or `~1.2.0`; use [`range` queries]({{site.url}}{{site.baseurl}}/query-dsl/term/range/) instead.

0 commit comments

Comments
 (0)