If you just replace fields
with properties
in your example then, as Biplab said, Elasticsearch will give you an exception:
"reason": "Failed to parse mapping [doc]: Mapping definition for [city] \
has unsupported parameters: [properties : {raw={type=keyword}}]",
So what are the properties
?
properties
basically declare that you will send a complex JSON object here.
The closest mapping using properties
instead of fields
from your example would look like:
PUT my_index_with_properties
{
"mappings": {
"doc": {
"properties": {
"city": {
"properties": {
"name": {
"type": "text"
},
"name_keyword": {
"type": "keyword"
}
}
}
}
}
}
}
And the document you would have to insert will look like this:
POST my_index_with_properties/doc
{
"city": {
"name": "New York",
"name_keyword": "New York"
}
}
Note that "New York"
is repeated twice.
Here you can issue a full-text query with match
:
POST my_index_with_properties/doc/_search
{
"query": {
"match": {
"city.name": "york"
}
}
}
Or an exact search with a term
query:
POST my_index_with_properties/doc/_search
{
"query": {
"term": {
"city.name_keyword": "New York"
}
}
}
Note that we are querying different fields.
And how is it different from fields
?
Using the example with fields
, as you posted it, we can send a document that looks like this:
POST my_index/doc
{
"city": "New York"
}
There is no explicit data duplication as you can see. But in fact, underneath Elasticsearch is doing this duplication for you.
Now we can use the city
field for full-text search:
POST my_index/doc/_search
{
"query": {
"match": {
"city": "york"
}
}
}
It will not work for the exact search though. The following query will return nothing, because the field city
is tokenized and lowercased, and the argument of the term
query is not:
POST my_index/doc/_search
{
"query": {
"term": {
"city": "New York"
}
}
}
This exact search query instead will work:
POST my_index/doc/_search
{
"query": {
"term": {
"city.keyword": "New York"
}
}
}
Because with the fields
in the mapping we have just asked Elasticsearch to index that city
field yet another time, as a keyword
, and to use this field we have to type city.keyword
.
So, as a conclusion, fields
is just a way to tell Elasticsearch that you want it to treat the same data field in several different ways. It may come handy when indexing text in different languages, for example.