/// <summary> /// 工厂方法创建一个新的 sort 控制结果将如何排序。. /// </summary> public static SortField Sort <T>(Expression <Func <T, object> > expression, SortOrder sortOrder) { var propertySearchName = (PropertySearchNameAttribute) LoadAttributeHelper.LoadAttributeByType <T, PropertySearchNameAttribute>(expression); return(new SortField { Field = propertySearchName.Name, Order = sortOrder }); }
/// <summary> /// 工厂方法创建一个新的 IFieldPredicate 谓语: [FieldName] [Operator] [Value]. /// </summary> /// <typeparam name="T">实例类型</typeparam> /// <param name="expression">返回左操作数的表达式 [FieldName].</param> /// <param name="op">比较运算符</param> /// <param name="value">谓语的值.</param> /// <returns>An instance of IFieldPredicate.</returns> public static IFieldPredicate Field <T>(Expression <Func <T, object> > expression, ExpressOperator op, object value) where T : class { var propertySearchName = (PropertySearchNameAttribute) LoadAttributeHelper.LoadAttributeByType <T, PropertySearchNameAttribute>(expression); return(new FieldPredicate <T> { PropertyName = propertySearchName.Name, ExpressOperator = op, Value = value }); }
/// <summary> /// FieldTerms /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expression"></param> /// <param name="searchKey"></param> /// <param name="size"></param> /// <returns></returns> public static IFieldTerms FieldTerms <T>(Expression <Func <T, object> > expression, string searchKey, int size) where T : class { var propertySearchName = (PropertySearchNameAttribute) LoadAttributeHelper.LoadAttributeByType <T, PropertySearchNameAttribute>(expression); return(new FieldTerms { SearchKey = searchKey, PropertyName = propertySearchName.Name, Size = size }); }
/// <summary> /// 初始化高亮配置 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="searchRequest"></param> /// <param name="config"></param> /// <returns></returns> public static ISearchRequest InitHighlight <T>(this ISearchRequest searchRequest, HighlightConfig <T> config) { if (config == null) { return(searchRequest); } var dic = new Dictionary <Field, IHighlightField>(); foreach (var expression in config.HighlightConfigExpression) { var propertySearchName = (PropertySearchNameAttribute) LoadAttributeHelper.LoadAttributeByType <T, PropertySearchNameAttribute>(expression); dic.Add(propertySearchName.Name, new HighlightField()); } searchRequest.Highlight = new Highlight { PreTags = new[] { $"<{config.Tag}>" }, PostTags = new[] { $"</{config.Tag}>" }, Encoder = HighlighterEncoder.Html, Fields = dic }; return(searchRequest); }
/// <summary> /// Search /// </summary> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="requestContentDto"></param> public ContentResponse Search(int pageIndex, int pageSize, RequestContentDto requestContentDto) { var elasticsearchPage = new ElasticsearchPage <Content>("content_test") { PageIndex = pageIndex, PageSize = pageSize }; #region terms 分组 var terms = new List <IFieldTerms>(); var classificationGroupBy = "searchKey_classification"; var brandGroupBy = "searchKey_brand"; #endregion var searchRequest = elasticsearchPage.InitSearchRequest(); var predicateList = new List <IPredicate>(); //分类ID if (requestContentDto.CategoryId != null) { predicateList.Add(Predicates.Field <Content>(x => x.ClassificationCode, ExpressOperator.Like, requestContentDto.CategoryId)); } else { terms.Add(Predicates.FieldTerms <Content>(x => x.ClassificationGroupBy, classificationGroupBy, 200)); } //品牌 if (string.IsNullOrWhiteSpace(requestContentDto.Brand)) { terms.Add(Predicates.FieldTerms <Content>(x => x.BrandGroupBy, brandGroupBy, 200)); } //供应商名称 if (!string.IsNullOrWhiteSpace(requestContentDto.BaseType)) { predicateList.Add(Predicates.Field <Content>(x => x.BaseType, ExpressOperator.Like, requestContentDto.BaseType)); } //是否自营 if (requestContentDto.IsSelfSupport == 1) { predicateList.Add(Predicates.Field <Content>(x => x.IsSelfSupport, ExpressOperator.Eq, requestContentDto.IsSelfSupport)); } //最大价格 if (requestContentDto.MaxPrice != null) { predicateList.Add(Predicates.Field <Content>(x => x.UnitPrice, ExpressOperator.Le, requestContentDto.MaxPrice)); } //最小价格 if (requestContentDto.MinPrice != null) { predicateList.Add(Predicates.Field <Content>(x => x.UnitPrice, ExpressOperator.Ge, requestContentDto.MinPrice)); } //关键词 if (!string.IsNullOrWhiteSpace(requestContentDto.SearchKey)) { predicateList.Add(Predicates.Field <Content>(x => x.Title, ExpressOperator.Like, requestContentDto.SearchKey)); } //规整排序 var sortConfig = SortOrderRule(requestContentDto.SortKey); var sorts = new List <ISort> { Predicates.Sort <Content>(sortConfig.Key, sortConfig.SortOrder) }; var predicate = Predicates.Group(GroupOperator.And, predicateList.ToArray()); //构建或查询 var predicateListOr = new List <IPredicate>(); if (!string.IsNullOrWhiteSpace(requestContentDto.Brand)) { var array = requestContentDto.Brand.Split(',').ToList(); predicateListOr .AddRange(array.Select (item => Predicates.Field <Content>(x => x.Brand, ExpressOperator.Like, item))); } var predicateOr = Predicates.Group(GroupOperator.Or, predicateListOr.ToArray()); var predicatecCombination = new List <IPredicate> { predicate, predicateOr }; var pgCombination = Predicates.Group(GroupOperator.And, predicatecCombination.ToArray()); searchRequest.InitQueryContainer(pgCombination) .InitSort(sorts) .InitHighlight(requestContentDto.HighlightConfigEntity) .InitGroupBy(terms); var data = _searchProvider.SearchPage(searchRequest); #region terms 分组赋值 var classificationResponses = requestContentDto.CategoryId != null ? null : data.Aggregations.Terms(classificationGroupBy).Buckets .Select(x => new ClassificationResponse { Key = x.Key.ToString(), DocCount = x.DocCount }).ToList(); var brandResponses = !string.IsNullOrWhiteSpace(requestContentDto.Brand) ? null : data.Aggregations.Terms(brandGroupBy).Buckets .Select(x => new BrandResponse { Key = x.Key.ToString(), DocCount = x.DocCount }).ToList(); #endregion //初始化 #region 高亮 var titlePropertySearchName = (PropertySearchNameAttribute) LoadAttributeHelper.LoadAttributeByType <Content, PropertySearchNameAttribute>(x => x.Title); var list = data.Hits.Select(c => new Content { Key = c.Source.Key, Title = (string)c.Highlights.Highlight(c.Source.Title, titlePropertySearchName.Name), ImgUrl = c.Source.ImgUrl, BaseType = c.Source.BaseType, BelongMemberName = c.Source.BelongMemberName, Brand = c.Source.Brand, Code = c.Source.Code, BrandFirstLetters = c.Source.BrandFirstLetters, ClassificationName = c.Source.ClassificationName, ResourceStatus = c.Source.ResourceStatus, BrandGroupBy = c.Source.BrandGroupBy, ClassificationGroupBy = c.Source.ClassificationGroupBy, ClassificationCode = c.Source.ClassificationCode, IsSelfSupport = c.Source.IsSelfSupport, UnitPrice = c.Source.UnitPrice }).ToList(); #endregion var contentResponse = new ContentResponse { Records = (int)data.Total, PageIndex = elasticsearchPage.PageIndex, PageSize = elasticsearchPage.PageSize, Contents = list, BrandResponses = brandResponses, ClassificationResponses = classificationResponses }; return(contentResponse); }