protected virtual IndexDocument CreateDocument(string productId, IList <Price> prices) { var document = new IndexDocument(productId); if (prices != null) { foreach (var price in prices) { document.Add(new IndexDocumentField($"price_{price.Currency}_{price.PricelistId}".ToLowerInvariant(), price.EffectiveValue) { IsRetrievable = true, IsFilterable = true }); // Save additional pricing fields for convinient user searches, store price with currency and without one document.Add(new IndexDocumentField($"price_{price.Currency}".ToLowerInvariant(), price.EffectiveValue) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); document.Add(new IndexDocumentField("price", price.EffectiveValue) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } } document.Add(new IndexDocumentField("is", prices?.Count > 0 ? "priced" : "unpriced") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); return(document); }
protected virtual void IndexProductVariation(IndexDocument document, CatalogProduct variation) { if (variation.ProductType == "Physical") { document.Add(new IndexDocumentField("type", "physical") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); IndexIsProperty(document, "physical"); } if (variation.ProductType == "Digital") { document.Add(new IndexDocumentField("type", "digital") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); IndexIsProperty(document, "digital"); } document.Add(new IndexDocumentField("code", variation.Code) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); // add the variation code to content document.Add(new IndexDocumentField("__content", variation.Code) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); IndexCustomProperties(document, variation.Properties, new[] { PropertyType.Variation }); }
protected virtual void IndexCustomProperties(IndexDocument document, ICollection <Property> properties, ICollection <PropertyValue> propertyValues) { foreach (var propValue in propertyValues.Where(x => x.Value != null)) { var property = properties.FirstOrDefault(p => p.Name.EqualsInvariant(propValue.PropertyName) && p.ValueType == propValue.ValueType); var propertyName = propValue.PropertyName?.ToLowerInvariant(); if (!string.IsNullOrEmpty(propertyName)) { var isCollection = property?.Multivalue == true; switch (propValue.ValueType) { case PropertyValueType.Boolean: case PropertyValueType.DateTime: case PropertyValueType.Number: document.Add(new IndexDocumentField(propertyName, propValue.Value) { IsRetrievable = true, IsFilterable = true, IsCollection = isCollection }); break; case PropertyValueType.LongText: document.Add(new IndexDocumentField(propertyName, propValue.Value.ToString().ToLowerInvariant()) { IsRetrievable = true, IsSearchable = true, IsCollection = isCollection }); break; case PropertyValueType.ShortText: // do not tokenize small values as they will be used for lookups and filters document.Add(new IndexDocumentField(propertyName, propValue.Value.ToString()) { IsRetrievable = true, IsFilterable = true, IsCollection = isCollection }); break; } } // Add value to the searchable content field var contentField = string.Concat("__content", property != null && property.Multilanguage && !string.IsNullOrWhiteSpace(propValue.LanguageCode) ? "_" + propValue.LanguageCode.ToLowerInvariant() : string.Empty); switch (propValue.ValueType) { case PropertyValueType.LongText: case PropertyValueType.ShortText: var stringValue = propValue.Value.ToString(); if (!string.IsNullOrWhiteSpace(stringValue)) // don't index empty values { document.Add(new IndexDocumentField(contentField, stringValue.ToLower()) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); } break; } } }
private async Task <string> CreateDocAsync(CancellationToken cancellationToken) { var id = GetId(); var doc = new IndexDocument(); doc.Add(new IndexField("TestDocId", id, IndexingMode.Default, IndexStoringMode.Yes, IndexTermVector.Default)); doc.Add(new IndexField("DocType", "DocumentForValidityTest", IndexingMode.Default, IndexStoringMode.Yes, IndexTermVector.Default)); doc.Add(new IndexField("Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), IndexingMode.Default, IndexStoringMode.Yes, IndexTermVector.Default)); var docs = new[] { doc }; await _engine.WriteIndexAsync(null, null, docs, cancellationToken); return(id); }
public static void AddObjectFieldValue <T>(this IndexDocument document, T value) { document.Add(new IndexDocumentField(ObjectFieldName, value) { IsRetrievable = false, IsFilterable = false, IsSearchable = false }); }
protected static IndexDocument CreateDocument(string id, string fieldName) { var result = new IndexDocument(id); result.Add(new IndexDocumentField(fieldName, id)); return(result); }
public static void AddObjectFieldValue <T>(this IndexDocument document, T value) { document.Add(new IndexDocumentField(ObjectFieldName, SerializeObject(value)) { IsRetrievable = true }); }
protected virtual void IndexIsProperty(IndexDocument document, string value) { document.Add(new IndexDocumentField("is", value) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); }
protected virtual void IndexDynamicProperty(IndexDocument document, DynamicObjectProperty property) { var propertyName = property.Name?.ToLowerInvariant(); if (!string.IsNullOrEmpty(propertyName)) { var isCollection = property.IsDictionary || property.IsArray; IList <object> values; if (!property.IsDictionary) { values = property.Values.Where(x => x.Value != null) .Select(x => x.Value) .ToList(); } else { //add all locales in dictionary to searchIndex values = property.Values.Select(x => x.Value) .Cast <DynamicPropertyDictionaryItem>() .Where(x => !string.IsNullOrEmpty(x.Name)) .Select(x => x.Name) .ToList <object>(); } if (values.Any()) { document.Add(new IndexDocumentField(propertyName, values) { IsRetrievable = true, IsFilterable = true, IsCollection = isCollection }); } } }
public static void AddFilterableValue(this IndexDocument document, string name, object value) { if (value != null) { document.Add(new IndexDocumentField(name, value) { IsRetrievable = true, IsFilterable = true }); } }
/// <summary> /// Adds given value to the searchable '__content' field /// </summary> /// <param name="document"></param> /// <param name="value"></param> public static void AddSearchableValue(this IndexDocument document, string value) { if (!string.IsNullOrWhiteSpace(value)) { document.Add(new IndexDocumentField(SearchableFieldName, value) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); } }
/// <summary> /// Adds given value to the filterable field with given name and to the searchable '__content' field /// </summary> /// <param name="document"></param> /// <param name="name"></param> /// <param name="value"></param> public static void AddFilterableAndSearchableValue(this IndexDocument document, string name, string value) { if (!string.IsNullOrWhiteSpace(value)) { document.Add(new IndexDocumentField(name, value) { IsRetrievable = true, IsFilterable = true }); document.AddSearchableValue(value); } }
protected override IndexDocument CreateDocument(CatalogProduct product) { var document = new IndexDocument(product.Id); // adding an index field for the first letter of name document.Add(new IndexDocumentField(FiltersHelper.FirstLetterField, product.Name.ToUpper()[0]) { IsRetrievable = true, IsFilterable = true //IsSearchable = true }); return(document); }
protected virtual IndexDocument CreateDocument(Category category, string[] tags) { var document = new IndexDocument(category.Id); foreach (var tag in tags) { document.Add(new IndexDocumentField(Constants.UserGroupsFieldName, tag) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } return(document); }
public static void AddFilterableValues(this IndexDocument document, string name, ICollection <string> values) { if (values?.Any() == true) { foreach (var value in values) { if (!string.IsNullOrWhiteSpace(value)) { document.Add(new IndexDocumentField(name, value) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } } } }
protected virtual IndexDocument CreateDocument(CatalogProduct product, string[] tags) { var document = new IndexDocument(product.Id); if (tags.IsNullOrEmpty()) { tags = new[] { Constants.UserGroupsAnyValue }; } foreach (var tag in tags) { document.Add(new IndexDocumentField(Constants.UserGroupsFieldName, tag) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } return(document); }
protected virtual void IndexDynamicProperty(IndexDocument document, DynamicProperty property, DynamicObjectProperty objectProperty) { var propertyName = property.Name?.ToLowerInvariant(); if (!string.IsNullOrEmpty(propertyName)) { IList <object> values = null; var isCollection = property.IsDictionary || property.IsArray; if (objectProperty != null) { if (!objectProperty.IsDictionary) { values = objectProperty.Values.Where(x => x.Value != null) .Select(x => x.Value) .ToList(); } else { //add all locales in dictionary to searchIndex values = objectProperty.Values.Select(x => x.Value) .Cast <DynamicPropertyDictionaryItem>() .Where(x => !string.IsNullOrEmpty(x.Name)) .Select(x => x.Name) .ToList <object>(); } } // Use default or empty value for the property in index to be able to filter by it if (values.IsNullOrEmpty()) { values = new[] { property.IsRequired ? GetDynamicPropertyDefaultValue(property) ?? NoValueString : NoValueString }; } document.Add(new IndexDocumentField(propertyName, values) { IsRetrievable = true, IsFilterable = true, IsCollection = isCollection }); } }
public async Task <IList <IndexDocument> > GetDocumentsAsync(IList <string> documentIds) { var now = DateTime.UtcNow; var result = new List <IndexDocument>(); var inventoriesGroupByProduct = _inventoryService.GetProductsInventoryInfos(documentIds).GroupBy(x => x.ProductId); foreach (var productInventories in inventoriesGroupByProduct) { var document = new IndexDocument(productInventories.Key); foreach (var inventory in productInventories) { if (inventory.IsAvailableOn(now)) { document.Add(new IndexDocumentField("available_in", inventory.FulfillmentCenterId.ToLowerInvariant()) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } result.Add(document); } } return(await Task.FromResult(result)); }
protected virtual IndexDocument CreateDocument(string productId, IList <Price> prices) { var document = new IndexDocument(productId); if (prices != null) { if (_settingsManager.GetValue(ModuleConstants.Settings.General.StorePricesInIndex.Name, false)) { document.Add(new IndexDocumentField("__prices", prices) { IsRetrievable = false, IsFilterable = false, IsCollection = false }); } foreach (var price in prices) { document.Add(new IndexDocumentField($"price_{price.Currency}_{price.PricelistId}".ToLowerInvariant(), price.EffectiveValue) { IsRetrievable = true, IsFilterable = true }); // Save additional pricing fields for convinient user searches, store price with currency and without one document.Add(new IndexDocumentField($"price_{price.Currency}".ToLowerInvariant(), price.EffectiveValue) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); document.Add(new IndexDocumentField("price", price.EffectiveValue) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } document.Add(new IndexDocumentField("is", prices.Any(x => x.Sale > 0) ? "sale" : "nosale") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } document.Add(new IndexDocumentField("is", prices?.Count > 0 ? "priced" : "unpriced") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); return(document); }
protected virtual void IndexCustomProperties(IndexDocument document, ICollection <Property> properties, ICollection <PropertyType> contentPropertyTypes) { foreach (var property in properties) { foreach (var propValue in property.Values?.Where(x => x.Value != null) ?? Array.Empty <PropertyValue>()) { var propertyName = propValue.PropertyName?.ToLowerInvariant(); if (!string.IsNullOrEmpty(propertyName)) { var isCollection = property?.Multivalue == true; switch (propValue.ValueType) { case PropertyValueType.Boolean: case PropertyValueType.DateTime: case PropertyValueType.Integer: case PropertyValueType.Number: document.Add(new IndexDocumentField(propertyName, propValue.Value) { IsRetrievable = true, IsFilterable = true, IsCollection = isCollection }); break; case PropertyValueType.LongText: document.Add(new IndexDocumentField(propertyName, propValue.Value.ToString().ToLowerInvariant()) { IsRetrievable = true, IsSearchable = true, IsCollection = isCollection }); break; case PropertyValueType.ShortText: // Index alias when it is available instead of display value. // Do not tokenize small values as they will be used for lookups and filters. var shortTextValue = propValue.Alias ?? propValue.Value.ToString(); document.Add(new IndexDocumentField(propertyName, shortTextValue) { IsRetrievable = true, IsFilterable = true, IsCollection = isCollection }); break; case PropertyValueType.GeoPoint: document.Add(new IndexDocumentField(propertyName, GeoPoint.TryParse((string)propValue.Value)) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); break; } } // Add value to the searchable content field if property type is uknown or if it is present in the provided list if (property == null || contentPropertyTypes == null || contentPropertyTypes.Contains(property.Type)) { var contentField = string.Concat("__content", property != null && property.Multilanguage && !string.IsNullOrWhiteSpace(propValue.LanguageCode) ? "_" + propValue.LanguageCode.ToLowerInvariant() : string.Empty); switch (propValue.ValueType) { case PropertyValueType.LongText: case PropertyValueType.ShortText: var stringValue = propValue.Value.ToString(); if (!string.IsNullOrWhiteSpace(stringValue)) // don't index empty values { document.Add(new IndexDocumentField(contentField, stringValue.ToLower()) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); } break; } } } } }
protected virtual IndexDocument CreateDocument(CatalogProduct product) { var document = new IndexDocument(product.Id); document.Add(new IndexDocumentField("__type", product.GetType().Name) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("__sort", product.Name) { IsRetrievable = true, IsFilterable = true }); var statusField = product.IsActive != true || product.MainProductId != null ? "hidden" : "visible"; IndexIsProperty(document, statusField); IndexIsProperty(document, string.IsNullOrEmpty(product.MainProductId) ? "product" : "variation"); IndexIsProperty(document, product.Code); document.Add(new IndexDocumentField("status", statusField) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("code", product.Code) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); document.Add(new IndexDocumentField("name", product.Name) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("startdate", product.StartDate) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("enddate", product.EndDate ?? DateTime.MaxValue) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("createddate", product.CreatedDate) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("lastmodifieddate", product.ModifiedDate ?? DateTime.MaxValue) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("modifieddate", product.ModifiedDate ?? DateTime.MaxValue) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("priority", product.Priority) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("vendor", product.Vendor ?? "") { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("productType", product.ProductType ?? "") { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("mainProductId", product.MainProductId ?? "") { IsRetrievable = true, IsFilterable = true }); // Add priority in virtual categories to search index if (product.Links != null) { foreach (var link in product.Links) { document.Add(new IndexDocumentField($"priority_{link.CatalogId}_{link.CategoryId}", link.Priority) { IsRetrievable = true, IsFilterable = true }); } } // Add catalogs to search index var catalogs = product.Outlines .Select(o => o.Items.First().Id) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); foreach (var catalogId in catalogs) { document.Add(new IndexDocumentField("catalog", catalogId.ToLowerInvariant()) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } // Add outlines to search index var outlineStrings = GetOutlineStrings(product.Outlines); foreach (var outline in outlineStrings) { document.Add(new IndexDocumentField("__outline", outline.ToLowerInvariant()) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } // Types of properties which values should be added to the searchable __content field var contentPropertyTypes = new[] { PropertyType.Product, PropertyType.Variation }; // Index custom product properties IndexCustomProperties(document, product.Properties, product.PropertyValues, contentPropertyTypes); //Index product category properties if (product.Category != null) { IndexCustomProperties(document, product.Category.Properties, product.Category.PropertyValues, contentPropertyTypes); } //Index catalog properties if (product.Catalog != null) { IndexCustomProperties(document, product.Catalog.Properties, product.Catalog.PropertyValues, contentPropertyTypes); } if (product.Variations != null) { if (product.Variations.Any(c => c.ProductType == "Physical")) { document.Add(new IndexDocumentField("type", "physical") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); IndexIsProperty(document, "physical"); } if (product.Variations.Any(c => c.ProductType == "Digital")) { document.Add(new IndexDocumentField("type", "digital") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); IndexIsProperty(document, "digital"); } foreach (var variation in product.Variations) { document.Add(new IndexDocumentField("code", variation.Code) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); // add the variation code to content document.Add(new IndexDocumentField("__content", variation.Code) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); IndexCustomProperties(document, variation.Properties, variation.PropertyValues, contentPropertyTypes); } } // add to content document.Add(new IndexDocumentField("__content", product.Name) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); document.Add(new IndexDocumentField("__content", product.Code) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); if (StoreObjectsInIndex) { // Index serialized product var itemDto = product.ToWebModel(_blobUrlResolver); document.AddObjectFieldValue(itemDto); } return(document); }
public void Build(IIndexWriter writer, Dynamicweb.Diagnostics.Tracking.Tracker tracker) { #region Implementation writer.Open(openForAppend: false); if (!TaskManager.Context.ContainsKey("Database.ConnectionString")) { return; } using (var conn = new SqlConnection(TaskManager.Context["Database.ConnectionString"].ToString())) { #region Connection conn.Open(); // Get count using (var cmd = conn.CreateCommand()) { tracker.LogInformation("Getting count"); cmd.CommandText = "SELECT COUNT(AccessUserID) FROM AccessUser WHERE AccessUserType = 5"; tracker.Status.TotalCount = (int)cmd.ExecuteScalar(); } // Handle users using (var cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT AccessUserID, AccessUserUserName, AccessUserName, AccessUserEmail, AccessUserNewsletterAllowed, AccessUserGroups FROM AccessUser WHERE AccessUserType = 5"; using (var reader = cmd.ExecuteReader()) { tracker.LogInformation("Handling users"); while (reader.Read()) { #region Build document var doc = new IndexDocument(); for (var i = 0; i < reader.FieldCount; i++) { var name = reader.GetName(i); var value = reader.GetValue(i); if (name == "AccessUserGroups") { #region Handle groups if (reader.IsDBNull(i)) { continue; } var groupIds = value.ToString().Split(new[] { '@' }, StringSplitOptions.RemoveEmptyEntries); var groupIdList = groupIds .Select(id => id.Trim('@')) .Where(id => !string.IsNullOrEmpty(id)) .Select(int.Parse) .ToList(); if (groupIdList.Count > 0) { doc.Add("Groups", groupIdList); } #endregion } else { doc.Add(name, value); } } writer.AddDocument(doc); tracker.IncrementCounter(); #endregion } } } #endregion } #endregion }
protected virtual IndexDocument CreateDocument(string id, string name, string color, string date, int size, string location, string name2, DateTime?date2, params Price[] prices) { var doc = new IndexDocument(id); doc.Add(new IndexDocumentField("Content", name) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); doc.Add(new IndexDocumentField("Content", color) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); doc.Add(new IndexDocumentField("Code", id) { IsRetrievable = true, IsFilterable = true }); doc.Add(new IndexDocumentField("Name", name) { IsRetrievable = true, IsFilterable = true }); doc.Add(new IndexDocumentField("Color", color) { IsRetrievable = true, IsFilterable = true }); doc.Add(new IndexDocumentField("Size", size) { IsRetrievable = true, IsFilterable = true }); doc.Add(new IndexDocumentField("Date", DateTime.Parse(date)) { IsRetrievable = true, IsFilterable = true }); doc.Add(new IndexDocumentField("Location", GeoPoint.TryParse(location)) { IsRetrievable = true, IsFilterable = true }); doc.Add(new IndexDocumentField("Catalog", "Goods") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("Catalog", "Stuff") { IsRetrievable = true, IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("NumericCollection", size) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("NumericCollection", 10) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("NumericCollection", 20) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("Is", "Priced") { IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("Is", color) { IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("Is", id) { IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField("StoredField", "This value should not be processed in any way, it is just stored in the index.") { IsRetrievable = true }); foreach (var price in prices) { doc.Add(new IndexDocumentField($"Price_{price.Currency}_{price.Pricelist}", price.Amount) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); doc.Add(new IndexDocumentField($"Price_{price.Currency}", price.Amount) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } var hasMultiplePrices = prices.Length > 1; doc.Add(new IndexDocumentField("HasMultiplePrices", hasMultiplePrices) { IsRetrievable = true, IsFilterable = true }); // Adds extra fields to test mapping updates for indexer if (name2 != null) { doc.Add(new IndexDocumentField("Name 2", name2) { IsRetrievable = true, IsFilterable = true }); } if (date2 != null) { doc.Add(new IndexDocumentField("Date (2)", date2) { IsRetrievable = true, IsFilterable = true }); } return(doc); }
protected virtual IndexDocument CreateDocument(Category category) { var document = new IndexDocument(category.Id); document.Add(new IndexDocumentField("__key", category.Id.ToLowerInvariant()) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("__type", category.GetType().Name) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("__sort", category.Name) { IsRetrievable = true, IsFilterable = true }); var statusField = category.IsActive != true ? "hidden" : "visible"; IndexIsProperty(document, statusField); IndexIsProperty(document, "category"); IndexIsProperty(document, category.Code); document.Add(new IndexDocumentField("status", statusField) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("code", category.Code) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("name", category.Name) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("createddate", category.CreatedDate) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("lastmodifieddate", category.ModifiedDate ?? DateTime.MaxValue) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("modifieddate", category.ModifiedDate ?? DateTime.MaxValue) { IsRetrievable = true, IsFilterable = true }); document.Add(new IndexDocumentField("priority", category.Priority) { IsRetrievable = true, IsFilterable = true }); // Add priority in virtual categories to search index if (category.Links != null) { foreach (var link in category.Links) { document.Add(new IndexDocumentField($"priority_{link.CatalogId}_{link.CategoryId}", link.Priority) { IsRetrievable = true, IsFilterable = true }); } } // Add catalogs to search index var catalogs = category.Outlines .Select(o => o.Items.First().Id) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); foreach (var catalogId in catalogs) { document.Add(new IndexDocumentField("catalog", catalogId.ToLowerInvariant()) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } // Add outlines to search index var outlineStrings = GetOutlineStrings(category.Outlines); foreach (var outline in outlineStrings) { document.Add(new IndexDocumentField("__outline", outline.ToLowerInvariant()) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } foreach (var outlineItem in GetOutlineStrings(category.Outlines, getNameLatestItem: true)) { document.Add(new IndexDocumentField($"__outline_named", outlineItem) { IsRetrievable = true, IsFilterable = true, IsCollection = true }); } IndexCustomProperties(document, category.Properties, new[] { PropertyType.Category }); // add to content document.Add(new IndexDocumentField("__content", category.Name) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); document.Add(new IndexDocumentField("__content", category.Code) { IsRetrievable = true, IsSearchable = true, IsCollection = true }); if (StoreObjectsInIndex) { // Index serialized category document.AddObjectFieldValue(category); } document.Add(new IndexDocumentField("parent", category.ParentId ?? category.CatalogId) { IsRetrievable = true, IsSearchable = true, IsFilterable = true }); return(document); }
/// <inheritdoc /> public IndexDocument GetIndexDocument(Node node, bool skipBinaries, bool isNew, out bool hasBinary) { if (node == null) { throw new ArgumentNullException(nameof(node)); } hasBinary = false; if (!ContentType.GetByName(node.NodeType.Name)?.IndexingEnabled ?? false) { return(IndexDocument.NotIndexedDocument); } var textEtract = new StringBuilder(); // ReSharper disable once SuspiciousTypeConversion.Global // There may be external implementations. var doc = new IndexDocument(); var ixnode = node as IIndexableDocument; var faultedFieldNames = new List <string>(); if (ixnode == null) { doc.Add(new IndexField(IndexFieldName.NodeId, node.Id, IndexingMode.AnalyzedNoNorms, IndexStoringMode.Yes, IndexTermVector.No)); doc.Add(new IndexField(IndexFieldName.VersionId, node.VersionId, IndexingMode.AnalyzedNoNorms, IndexStoringMode.Yes, IndexTermVector.No)); doc.Add(new IndexField(IndexFieldName.Version, node.Version.ToString(), IndexingMode.Analyzed, IndexStoringMode.Yes, IndexTermVector.No)); doc.Add(new IndexField(IndexFieldName.OwnerId, node.OwnerId, IndexingMode.AnalyzedNoNorms, IndexStoringMode.Yes, IndexTermVector.No)); doc.Add(new IndexField(IndexFieldName.CreatedById, node.CreatedById, IndexingMode.AnalyzedNoNorms, IndexStoringMode.Yes, IndexTermVector.No)); doc.Add(new IndexField(IndexFieldName.ModifiedById, node.ModifiedById, IndexingMode.AnalyzedNoNorms, IndexStoringMode.Yes, IndexTermVector.No)); } else { foreach (var field in ixnode.GetIndexableFields()) { if (IndexDocument.ForbiddenFields.Contains(field.Name)) { continue; } if (IndexDocument.PostponedFields.Contains(field.Name)) { continue; } if (node.SavingState != ContentSavingState.Finalized && (field.IsBinaryField || SkippedMultistepFields.Contains(field.Name))) { continue; } if (skipBinaries && (field.IsBinaryField)) { if (TextExtractor.TextExtractingWillBePotentiallySlow((BinaryData)((BinaryField)field).GetData())) { hasBinary = true; continue; } } IEnumerable <IndexField> indexFields = null; string extract = null; try { indexFields = field.GetIndexFields(out extract); } catch (Exception) { faultedFieldNames.Add(field.Name); } if (!String.IsNullOrEmpty(extract)) // do not add extra line if extract is empty { try { textEtract.AppendLine(extract); } catch (OutOfMemoryException) { SnLog.WriteWarning("Out of memory error during indexing.", EventId.Indexing, properties: new Dictionary <string, object> { { "Path", node.Path }, { "Field", field.Name } }); } } if (indexFields != null) { foreach (var indexField in indexFields) { doc.Add(indexField); } } } } var isInherited = true; if (!isNew) { isInherited = node.IsInherited; } doc.Add(new IndexField(IndexFieldName.IsInherited, isInherited, IndexingMode.Analyzed, IndexStoringMode.Yes, IndexTermVector.Default)); doc.Add(new IndexField(IndexFieldName.IsMajor, node.Version.IsMajor, IndexingMode.Analyzed, IndexStoringMode.Yes, IndexTermVector.Default)); doc.Add(new IndexField(IndexFieldName.IsPublic, node.Version.Status == VersionStatus.Approved, IndexingMode.Analyzed, IndexStoringMode.Yes, IndexTermVector.Default)); doc.Add(new IndexField(IndexFieldName.AllText, textEtract.ToString(), IndexingMode.Analyzed, IndexStoringMode.No, IndexTermVector.Default)); if (faultedFieldNames.Any()) { doc.Add(new IndexField(IndexFieldName.IsFaulted, true, IndexingMode.NotAnalyzed, IndexStoringMode.Yes, IndexTermVector.Default)); foreach (var faultedFieldName in faultedFieldNames) { doc.Add(new IndexField(IndexFieldName.FaultedFieldName, faultedFieldName, IndexingMode.NotAnalyzed, IndexStoringMode.Yes, IndexTermVector.Default)); } } // Validation if (!doc.HasField(IndexFieldName.NodeId)) { throw new InvalidOperationException("Invalid empty field value for field: " + IndexFieldName.NodeId); } if (!doc.HasField(IndexFieldName.VersionId)) { throw new InvalidOperationException("Invalid empty field value for field: " + IndexFieldName.VersionId); } return(doc); }
/// <inheritdoc /> public IndexDocument CompleteIndexDocument(Node node, IndexDocument baseDocument) { if (node == null) { throw new ArgumentNullException(nameof(node)); } var textEtract = new StringBuilder(baseDocument.GetStringValue(IndexFieldName.AllText)); var faultedFieldNames = new List <string>(); if (node is IIndexableDocument ixnode) { foreach (var field in ixnode.GetIndexableFields()) { if (IndexDocument.ForbiddenFields.Contains(field.Name)) { continue; } if (IndexDocument.PostponedFields.Contains(field.Name)) { continue; } if (node.SavingState != ContentSavingState.Finalized && (field.IsBinaryField || SkippedMultistepFields.Contains(field.Name))) { continue; } if (!field.IsBinaryField) { continue; } if (!TextExtractor.TextExtractingWillBePotentiallySlow((BinaryData)((BinaryField)field).GetData())) { continue; } IEnumerable <IndexField> indexFields = null; string extract = null; try { indexFields = field.GetIndexFields(out extract); } catch (Exception) { faultedFieldNames.Add(field.Name); } if (!String.IsNullOrEmpty(extract)) // do not add extra line if extract is empty { try { textEtract.AppendLine(extract); } catch (OutOfMemoryException) { SnLog.WriteWarning("Out of memory error during indexing.", EventId.Indexing, properties: new Dictionary <string, object> { { "Path", node.Path }, { "Field", field.Name } }); } } if (indexFields != null) { foreach (var indexField in indexFields) { baseDocument.Add(indexField); } } } } baseDocument.Add(new IndexField(IndexFieldName.AllText, textEtract.ToString(), IndexingMode.Analyzed, IndexStoringMode.No, IndexTermVector.Default)); if (faultedFieldNames.Any()) { if (!baseDocument.GetBooleanValue(IndexFieldName.IsFaulted)) { baseDocument.Add(new IndexField(IndexFieldName.IsFaulted, true, IndexingMode.NotAnalyzed, IndexStoringMode.Yes, IndexTermVector.Default)); } foreach (var faultedFieldName in faultedFieldNames) { baseDocument.Add(new IndexField(IndexFieldName.FaultedFieldName, faultedFieldName, IndexingMode.NotAnalyzed, IndexStoringMode.Yes, IndexTermVector.Default)); } } return(baseDocument); }
private void SetDocumentFlag(IndexDocument doc, string fieldName, bool value) { doc.Add(new IndexField(fieldName, value, IndexingMode.NotAnalyzed, IndexStoringMode.Yes, IndexTermVector.No)); }