public static BoolFilter<ESDocument> CreateQueryForValue(ISearchCriteria criteria, ISearchFilter filter, ISearchFilterValue value) { var query = new BoolFilter<ESDocument>(); var field = filter.Key.ToLower(); if (filter.GetType() == typeof(PriceRangeFilter)) { var tempQuery = CreatePriceRangeFilter(criteria, field, value as RangeFilterValue); if (tempQuery != null) { query.Must(q => q.Bool(b => tempQuery)); } } else { if (value.GetType() == typeof(AttributeFilterValue)) { query.Must(q => q.Term(t => t.Field(field).Value(((AttributeFilterValue)value).Value))); } else if (value.GetType() == typeof(RangeFilterValue)) { var tempValue = value as RangeFilterValue; var tempFilter = new RangeFilter<ESDocument>(); tempFilter.Field(field).From(tempValue.Lower).To(tempValue.Upper).IncludeLower(true).IncludeUpper(false); query.Should(q => q.Range(r => tempFilter)); } } return query; }
/* /// <summary> /// Converts the specified filter to filter model. /// </summary> /// <param name="helper"></param> /// <param name="filter">The search filter.</param> /// <returns>Filter model</returns> public static Facet Convert(this IBrowseFilterService helper, ISearchFilter filter) { var model = new Facet(); if (filter is AttributeFilter) { var prop = filter as AttributeFilter; model.Field = prop.Key; model.Label = prop.Key; model.FacetType = "attr"; model.Values = prop.Values //model.Label = ClientContext.Clients.CreateCatalogClient().GetPropertyName(prop.Key); //model.Name = string.IsNullOrEmpty(model.Name) ? model.Key : model.Name; return model; } if (filter is RangeFilter) { var prop = filter as RangeFilter; model.Field = prop.Key; model.Label = prop.Key; //model.Name = ClientContext.Clients.CreateCatalogClient().GetPropertyName(prop.Key); //model.Name = string.IsNullOrEmpty(model.Name) ? model.Key : model.Name; return model; } if (filter is PriceRangeFilter) { var prop = filter as PriceRangeFilter; model.Field = prop.Key; model.Label = "Price"; return model; } if (filter is CategoryFilter) { var prop = filter as CategoryFilter; model.Field = prop.Key; model.Label = "Category"; return model; } return null; } public static FacetValue ToModel(this AttributeFilterValue value) { var ret = new FacetValue() { Value = value.Value }; return ret; } /// <summary> /// Converts the specified filter value to facet model. /// </summary> /// <param name="helper"></param> /// <param name="val">The search filter value.</param> /// <returns>facet model</returns> public static FacetModel Convert(this IBrowseFilterService helper, ISearchFilterValue val) { var model = new FacetModel(); if (val is AttributeFilterValue) { var v = val as AttributeFilterValue; model.Key = v.Id; model.Name = v.Value; return model; } if (val is CategoryFilterValue) { var v = val as CategoryFilterValue; model.Key = v.Id; model.Name = v.Name; return model; } if (val is RangeFilterValue) { var v = val as RangeFilterValue; model.Key = v.Id; var name = String.Empty; if (v.Displays != null) { var disp = (from d in v.Displays where d.Language == "en" select d).SingleOrDefault(); if (disp != null) { name = disp.Value; } } model.Name = name; return model; } return null; } /// <summary> /// Converts the specified facet groups into filter model. /// </summary> /// <param name="helper">The helper.</param> /// <param name="groups">The groups.</param> /// <returns> /// FilterModel[][]. /// </returns> public static FilterModel[] Convert(this IBrowseFilterService helper, FacetGroup[] groups) { var list = new List<FilterModel>(); if (groups != null) { list.AddRange(groups.Select(x => Convert(helper, x))); } return list.ToArray(); } /// <summary> /// Converts the specified facet group. /// </summary> /// <param name="helper">The helper.</param> /// <param name="group">The facet group.</param> /// <returns> /// facet group /// </returns> public static FilterModel Convert(this IBrowseFilterService helper, FacetGroup group) { return new FilterModel { Key = @group.FieldName, Name = GetDescriptionFromFilter(@group.FieldName), Facets = @group.Facets.Select(x => Convert(helper, x)).ToArray() }; } /// <summary> /// Converts the specified facet to facet model. /// </summary> /// <param name="helper">The helper.</param> /// <param name="facet">The facet.</param> /// <returns> /// facet model /// </returns> public static FacetModel Convert(this IBrowseFilterService helper, Facet facet) { return new FacetModel { Key = facet.Key, Name = GetNameFromFilterValue(helper, facet), Count = facet.Count }; } * */ #region Public Methods and Operators public static ISearchFilter Convert(this IBrowseFilterService helper, ISearchFilter filter, string[] keys) { if (filter != null && keys != null) { // get values that we have filters set for var values = from v in filter.GetValues() where keys.Contains(v.Id, StringComparer.OrdinalIgnoreCase) select v; var attributeFilter = filter as AttributeFilter; if (attributeFilter != null) { var newFilter = new AttributeFilter(); newFilter.InjectFrom(filter); newFilter.Values = values.OfType<AttributeFilterValue>().ToArray(); return newFilter; } var rangeFilter = filter as RangeFilter; if (rangeFilter != null) { var newFilter = new RangeFilter(); newFilter.InjectFrom(filter); newFilter.Values = values.OfType<RangeFilterValue>().ToArray(); return newFilter; } var priceRangeFilter = filter as PriceRangeFilter; if (priceRangeFilter != null) { var newFilter = new PriceRangeFilter(); newFilter.InjectFrom(filter); newFilter.Values = values.OfType<RangeFilterValue>().ToArray(); return newFilter; } var categoryFilter = filter as CategoryFilter; if (categoryFilter != null) { var newFilter = new CategoryFilter(); newFilter.InjectFrom(filter); newFilter.Values = values.OfType<CategoryFilterValue>().ToArray(); return newFilter; } } return null; }
/// <summary> /// Creates the price range filter. /// </summary> /// <param name="criteria">The criteria.</param> /// <param name="field">The field.</param> /// <param name="value">The value.</param> /// <returns></returns> public static BoolFilter<ESDocument> CreatePriceRangeFilter(ISearchCriteria criteria, string field, RangeFilterValue value) { var query = new BoolFilter<ESDocument>(); var lowerbound = value.Lower; var upperbound = value.Upper; var lowerboundincluded = true; var upperboundincluded = false; var currency = criteria.Currency.ToLower(); // format is "fieldname_store_currency_pricelist" string[] pls = null; if (criteria is CatalogIndexedSearchCriteria) { pls = ((CatalogIndexedSearchCriteria)criteria).Pricelists; } var parentPriceList = String.Empty; // Create filter of type // price_USD_pricelist1:[100 TO 200} (-price_USD_pricelist1:[* TO *} +(price_USD_pricelist2:[100 TO 200} (-price_USD_pricelist2:[* TO *} (+price_USD_pricelist3[100 TO 200})))) if (pls == null || !pls.Any()) return null; var priceListId = pls[0].ToLower(); var filter = new RangeFilter<ESDocument>(); filter.Field(String.Format("{0}_{1}_{2}", field, currency, priceListId)).From(lowerbound).To(upperbound).IncludeLower(lowerboundincluded).IncludeUpper(upperboundincluded); //query.Should(q => q.ConstantScore(c => c.Filter(f => f.Range(r => filter)))); query.Should(q => q.Range(r => filter)); if (pls.Count() > 1) { var temp = CreatePriceRangeFilter(pls, 1, field, currency, lowerbound, upperbound, lowerboundincluded, upperboundincluded); query.Should(q => q.Bool(b => temp)); } //Query query = new ConstantScoreQuery(filter); return query; }
private static BoolFilter<ESDocument> CreatePriceRangeFilter(string[] priceLists, int index, string field, string currency, string lowerbound, string upperbound, bool lowerboundincluded, bool upperboundincluded) { var query = new BoolFilter<ESDocument>(); // create left part var filter = new RangeFilter<ESDocument>(); filter.Field(String.Format("{0}_{1}_{2}", field, currency, priceLists[index - 1].ToLower()))/*.From("*").To("*")*/.IncludeLower(lowerboundincluded).IncludeUpper(upperboundincluded); //query.MustNot(q => q.ConstantScore(c => c.Filter(f => f.Range(r => filter)))); query.MustNot(q => q.Range(r => filter)); // create right part if (index == priceLists.Count() - 1) // last element { var filter2 = new RangeFilter<ESDocument>(); filter2.Field(String.Format("{0}_{1}_{2}", field, currency, priceLists[index].ToLower())).From(lowerbound).To(upperbound).IncludeLower(lowerboundincluded).IncludeUpper(upperboundincluded); //query.Must(q => q.ConstantScore(c => c.Filter(f => f.Range(r => filter2)))); query.Must(q => q.Range(r => filter2)); } else { query.Should(q => q.Bool(b => CreatePriceRangeFilter(priceLists, index + 1, field, currency, lowerbound, upperbound, lowerboundincluded, upperboundincluded))); } return query; }
public void Can_get_item_facets_lucene() { var scope = "default"; var queryBuilder = new LuceneSearchQueryBuilder(); var conn = new SearchConnection(_LuceneStorageDir, scope); var provider = new LuceneSearchProvider(queryBuilder, conn); Debug.WriteLine("Lucene connection: {0}", conn.ToString()); if (Directory.Exists(_LuceneStorageDir)) { Directory.Delete(_LuceneStorageDir, true); } SearchHelper.CreateSampleIndex(provider, scope); var criteria = new CatalogIndexedSearchCriteria { SearchPhrase = "", IsFuzzySearch = true, Catalog = "goods", RecordsToRetrieve = 10, StartingRecord = 0, Currency = "USD", Pricelists = new[] { "default" } }; var filter = new AttributeFilter { Key = "Color" }; filter.Values = new[] { new AttributeFilterValue { Id = "red", Value = "red" }, new AttributeFilterValue { Id = "blue", Value = "blue" }, new AttributeFilterValue { Id = "black", Value = "black" } }; var rangefilter = new RangeFilter { Key = "size" }; rangefilter.Values = new[] { new RangeFilterValue { Id = "0_to_5", Lower = "0", Upper = "5" }, new RangeFilterValue { Id = "5_to_10", Lower = "5", Upper = "10" } }; var priceRangefilter = new PriceRangeFilter { Currency = "usd" }; priceRangefilter.Values = new[] { new RangeFilterValue { Id = "0_to_100", Lower = "0", Upper = "100" }, new RangeFilterValue { Id = "100_to_700", Lower = "100", Upper = "700" } }; criteria.Add(filter); criteria.Add(rangefilter); criteria.Add(priceRangefilter); var results = provider.Search(scope, criteria); Assert.True(results.DocCount == 4, String.Format("Returns {0} instead of 4", results.DocCount)); var redCount = GetFacetCount(results, "Color", "red"); Assert.True(redCount == 2, String.Format("Returns {0} facets of red instead of 2", redCount)); var priceCount = GetFacetCount(results, "Price", "0_to_100"); Assert.True(priceCount == 2, String.Format("Returns {0} facets of 0_to_100 prices instead of 2", priceCount)); var priceCount2 = GetFacetCount(results, "Price", "100_to_700"); Assert.True(priceCount2 == 2, String.Format("Returns {0} facets of 100_to_700 prices instead of 2", priceCount2)); var sizeCount = GetFacetCount(results, "size", "0_to_5"); Assert.True(sizeCount == 2, String.Format("Returns {0} facets of 0_to_5 size instead of 2", sizeCount)); var sizeCount2 = GetFacetCount(results, "size", "5_to_10"); Assert.True(sizeCount2 == 1, String.Format("Returns {0} facets of 5_to_10 size instead of 1", sizeCount2)); // only 1 result because upper bound is not included var outlineCount = results.Documents[0].Documents[0]["__outline"].Values.Count(); Assert.True(outlineCount == 2, String.Format("Returns {0} outlines instead of 2", outlineCount)); Directory.Delete(_LuceneStorageDir, true); }
public void Can_get_item_multiple_filters_lucene() { var scope = "default"; var queryBuilder = new LuceneSearchQueryBuilder(); var conn = new SearchConnection(_LuceneStorageDir, scope); var provider = new LuceneSearchProvider(queryBuilder, conn); Debug.WriteLine("Lucene connection: {0}", conn.ToString()); if (Directory.Exists(_LuceneStorageDir)) { Directory.Delete(_LuceneStorageDir, true); } SearchHelper.CreateSampleIndex(provider, scope); var criteria = new CatalogIndexedSearchCriteria { SearchPhrase = "", IsFuzzySearch = true, Catalog = "goods", RecordsToRetrieve = 10, StartingRecord = 0, Currency = "USD", Pricelists = new[] { "default" } }; var colorFilter = new AttributeFilter { Key = "Color" }; colorFilter.Values = new[] { new AttributeFilterValue { Id = "red", Value = "red" }, new AttributeFilterValue { Id = "blue", Value = "blue" }, new AttributeFilterValue { Id = "black", Value = "black" } }; var filter = new AttributeFilter { Key = "Color" }; filter.Values = new[] { new AttributeFilterValue { Id = "black", Value = "black" } }; var rangefilter = new RangeFilter { Key = "size" }; rangefilter.Values = new[] { new RangeFilterValue { Id = "0_to_5", Lower = "0", Upper = "5" }, new RangeFilterValue { Id = "5_to_10", Lower = "5", Upper = "11" } }; var priceRangefilter = new PriceRangeFilter { Currency = "usd" }; priceRangefilter.Values = new[] { new RangeFilterValue { Id = "100_to_700", Lower = "100", Upper = "700" } }; criteria.Add(colorFilter); criteria.Add(priceRangefilter); // add applied filters criteria.Apply(filter); //criteria.Apply(rangefilter); //criteria.Apply(priceRangefilter); var results = provider.Search(scope, criteria); var blackCount = GetFacetCount(results, "Color", "black"); Assert.True(blackCount == 1, String.Format("Returns {0} facets of black instead of 2", blackCount)); //Assert.True(results.DocCount == 1, String.Format("Returns {0} instead of 1", results.DocCount)); Directory.Delete(_LuceneStorageDir, true); }