I created an index in my Elasticsearch server and I'm using .Net client NEST to connect to it. Some of the index properties have multiple fields and I want to fill just the correct field.
I created the class 'document' to this mappaing. but I do not know how to access fields of property.
this is the mapping I have (summarized):
"mappings": {
"document": {
"properties": {
"baseUniqueID": {
"type": "keyword"
},
"description": {
"type": "text",
"fields": {
"en": {
"type": "text",
"analyzer": "english"
},
"fa": {
"type": "text",
"analyzer": "nofapersian"
},
"fr": {
"type": "text",
"analyzer": "french"
}
}
},
"documentDate": {
"type": "date"
},
"documentType_Id": {
"type": "keyword"
},
"id": {
"type": "long"
}
}
}
}
and the document class:
public class Document : BaseInt32KeyEntity
{
public string BaseUniqueID{ get; set; }
public int? Weight { get; set; }
public DateTime DocumentDate { get; set; }
public string Description { get; set; }
public int DocumentType_Id { get; set; }
}
}
How can I make an object of Document to fill just the field I want (here in this example description.en) and then use IndexDocument to add it to Elasticsearch? something like this:
Document doc = new Document();
doc.Description.en = "This is some description";
ElasticClient.IndexDocument(doc);
You can update an individual field with the Update API
var client = new ElasticClient();
var documentId = 1;
var partial = new
{
Description = "This is some description"
};
var updateResponse = client.Update<Document, object>(documentId, u => u
.Index("your_index")
.Doc(partial)
);
The .Index()
is only needed if you haven't set up an index convention for the Document
type. The document to update is modelled with a partial document because using Document
would result in sending default values for value types like the DocumentDate
and DocumentType_Id
properties.
doc.Description.en = "This is some description";
It's not possible to do this as this is not how multi-fields work. With multi-fields, a single document field input can be analyzed in numerous different ways to serve different search needs. In your example, Description
property value will be analyzed 4 different ways:
text
mapping.en
multi-field mapping.fa
multi-field mapping.fr
multi-field mappingThe results of analysis will be indexed into the inverted index to allow you to search and query on them, but the original JSON document sent to Elasticsearch will only contain the one "description"
field, which is what you will get back when you retrieve the _source
for the document (if the _source
is stored, which by default it is).
If you wanted to model these as separate fields on the document, the you could introduce a Description
type that has the necessary properties
public class Description
{
public string Standard { get;set; }
public string English { get;set; }
public string NoFaPersian{ get;set; }
public string French{ get;set; }
}
and then index it as an object
type mapping, configuring the analyzer for each
public class Document
{
public string BaseUniqueID { get; set; }
public int? Weight { get; set; }
public DateTime DocumentDate { get; set; }
public Description Description { get; set; }
public int DocumentType_Id { get; set; }
}
var indexResponse = client.CreateIndex("your_index", c => c
.Mappings(m => m
.Map<Document>(mm => mm
.AutoMap()
.Properties(p => p
.Object<Description>(o => o
.Name(n => n.Description)
.AutoMap()
.Properties(pp => pp
.Text(t => t.Name(n => n.Standard).Analyzer("standard"))
.Text(t => t.Name(n => n.English).Analyzer("english"))
.Text(t => t.Name(n => n.NoFaPersian).Analyzer("nofapersian"))
.Text(t => t.Name(n => n.French).Analyzer("french"))
)
)
)
)
)
);
which produces the following create index request
PUT http://localhost:9200/your_index?pretty=true
{
"mappings": {
"document": {
"properties": {
"baseUniqueID": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"weight": {
"type": "integer"
},
"documentDate": {
"type": "date"
},
"description": {
"type": "object",
"properties": {
"standard": {
"type": "text",
"analyzer": "standard"
},
"english": {
"type": "text",
"analyzer": "english"
},
"noFaPersian": {
"type": "text",
"analyzer": "nofapersian"
},
"french": {
"type": "text",
"analyzer": "french"
}
}
},
"documentType_Id": {
"type": "integer"
}
}
}
}
}