public virtual void Index(string scope, string documentType, IDocument document) { var core = GetCoreName(scope, documentType); if (!_pendingDocuments.ContainsKey(core)) { _pendingDocuments.Add(core, new List<ESDocument>()); } string mapping = null; if (!_mappings.ContainsKey(core)) { // Get mapping info if (Client.IndexExists(new IndexExistsCommand(scope))) { mapping = GetMappingFromServer(scope, documentType, core); } } else { mapping = _mappings[core]; } var submitMapping = false; var properties = new Properties<ESDocument>(); var localDocument = new ESDocument(); for (var index = 0; index < document.FieldCount; index++) { var field = document[index]; var key = field.Name.ToLower(); if (localDocument.ContainsKey(key)) { var objTemp = localDocument[key]; object[] objListTemp; var temp = objTemp as object[]; if (temp != null) { var objList = new List<object>(temp) { field.Value }; objListTemp = objList.ToArray(); } else { objListTemp = new[] { objTemp, field.Value }; } localDocument[key] = objListTemp; } else { if (String.IsNullOrEmpty(mapping) || !mapping.Contains(String.Format("\"{0}\"", field.Name))) { var type = field.Value != null ? field.Value.GetType() : null; var propertyMap = new CustomPropertyMap<ESDocument>(field.Name, type) .Store(field.ContainsAttribute(IndexStore.Yes)) .When(field.ContainsAttribute(IndexType.NotAnalyzed), p => p.Index(IndexState.not_analyzed)) .When(field.Name.StartsWith("__content", StringComparison.OrdinalIgnoreCase), p => p.Analyzer(SearchAnalyzer)) .When(Regex.Match(field.Name, "__content_en.*").Success, x => x.Analyzer("english")) .When(Regex.Match(field.Name, "__content_de.*").Success, x => x.Analyzer("german")) .When(Regex.Match(field.Name, "__content_ru.*").Success, x => x.Analyzer("russian")) .When(field.ContainsAttribute(IndexType.No), p => p.Index(IndexState.no)); properties.CustomProperty(field.Name, p => propertyMap); submitMapping = true; } localDocument.Add(key, field.Value); } } // submit mapping if (submitMapping) { //Use ngrams analyzer for search in the middle of word //http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/ngrams-compound-words.html var settings = new IndexSettingsBuilder() .Analysis(als => als .Analyzer(a => a.Custom(SearchAnalyzer, custom => custom .Tokenizer(DefaultTokenizers.standard) .Filter("trigrams_filter", DefaultTokenFilters.lowercase.ToString()))) .Filter(f => f.NGram("trigrams_filter", ng => ng .MinGram(3) .MaxGram(3)))).Build(); if (!Client.IndexExists(new IndexExistsCommand(scope))) { var response = Client.CreateIndex(new IndexCommand(scope), settings); _settingsUpdated = true; if (response.error != null) throw new IndexBuildException(response.error); } else if (!_settingsUpdated) { // We can't update settings on active index. // So we need to close it, then update settings and then open index back. Client.Close(new CloseCommand(scope)); Client.UpdateSettings(new UpdateSettingsCommand(scope), settings); Client.Open(new OpenCommand(scope)); _settingsUpdated = true; } var mapBuilder = new MapBuilder<ESDocument>(); var mappingNew = mapBuilder.RootObject(documentType, d => d.Properties(p => properties)).Build(); var result = Client.PutMapping(new PutMappingCommand(scope, documentType), mappingNew); if (!result.acknowledged && result.error != null) throw new IndexBuildException(result.error); GetMappingFromServer(scope, documentType, core); } _pendingDocuments[core].Add(localDocument); // Auto commit changes when limit is reached if (AutoCommit && _pendingDocuments[core].Count > AutoCommitCount) { Commit(scope); } }
public virtual void Index(string scope, string documentType, IDocument document) { var core = GetCoreName(scope, documentType); if (!_pendingDocuments.ContainsKey(core)) { _pendingDocuments.Add(core, new List<ESDocument>()); } string mapping = null; if (!_mappings.ContainsKey(core)) { // Get mapping info if (Client.IndexExists(new IndexExistsCommand(scope))) { try { mapping = Client.GetMapping(new GetMappingCommand(scope, documentType)); } catch (OperationException ex) { if (ex.HttpStatusCode != 404 || !ex.Message.Contains("TypeMissingException")) { throw; } } if (mapping != null) _mappings.Add(core, mapping); } } else { mapping = _mappings[core]; } var submitMapping = false; var properties = new Properties<ESDocument>(); var localDocument = new ESDocument(); for (var index = 0; index < document.FieldCount; index++) { var field = document[index]; var key = field.Name.ToLower(); if (localDocument.ContainsKey(key)) { var objTemp = localDocument[key]; object[] objListTemp; var temp = objTemp as object[]; if (temp != null) { var objList = new List<object>(temp) { field.Value }; objListTemp = objList.ToArray(); } else { objListTemp = new[] { objTemp, field.Value }; } localDocument[key] = objListTemp; } else { if (String.IsNullOrEmpty(mapping) || !mapping.Contains(String.Format("\"{0}\"", key))) { var type = field.Value != null ? field.Value.GetType() : null; var propertyMap = new CustomPropertyMap<ESDocument>(field.Name, type) .Store(field.ContainsAttribute(IndexStore.YES)) .When(field.ContainsAttribute(IndexType.NOT_ANALYZED), p => p.Index(IndexState.not_analyzed)) .When(field.ContainsAttribute(IndexType.NO), p => p.Index(IndexState.no)); properties.CustomProperty(field.Name, p => propertyMap); submitMapping = true; } localDocument.Add(key, field.Value); } } // submit mapping if (submitMapping) { if (!Client.IndexExists(new IndexExistsCommand(scope))) { var response = Client.CreateIndex(new IndexCommand(scope)); if (response.error != null) throw new IndexBuildException(response.error); } var mapBuilder = new MapBuilder<ESDocument>(); var mappingNew = mapBuilder.RootObject(documentType, d => d.Properties(p => properties)).Build(); var result = Client.PutMapping(new PutMappingCommand(scope, documentType), mappingNew); if (!result.acknowledged && result.error != null) throw new IndexBuildException(result.error); } _pendingDocuments[core].Add(localDocument); // Auto commit changes when limit is reached if (AutoCommit && _pendingDocuments[core].Count > AutoCommitCount) { Commit(scope); } }