• 【ElasticSearch+NetCore 第二篇】Nest封装


    using Elasticsearch.Net;
    using Nest;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace ESStudy.Website
    {
        public static class EsUtil
        {
            /// <summary>
            /// 获取ElasticClient
            /// </summary>
            /// <param name="url">ElasticSearch服务器地址</param>
            /// <param name="defaultIndex">默认索引名称</param>
            /// <param name="defaultType">默认类型</param>
            /// <returns></returns>
            public static ElasticClient Client(string url, string defaultIndex = "", string defaultType = "")
            {
                var uri = new Uri(url);
                var setting = new ConnectionSettings(uri);
    
                if (!string.IsNullOrWhiteSpace(defaultIndex))
                {
                    setting.DefaultIndex(defaultIndex);
                }
    
                if (!string.IsNullOrWhiteSpace(defaultType))
                {
                    setting.DefaultTypeName(defaultType);
                }
    
                return new ElasticClient(setting);
            }
    
            /// <summary>
            /// 获取ElasticClient
            /// </summary>
            /// <param name="urls">ElasticSearch集群地址</param>
            /// <param name="defaultIndex">默认索引名称</param>
            /// <param name="defaultType">默认类型</param>
            /// <returns></returns>
            public static ElasticClient Client(string[] urls, string defaultIndex = "", string defaultType = "")
            {
                var uris = urls.Select(h => new Uri(h)).ToArray();
                var pool = new SniffingConnectionPool(uris);
    
                var setting = new ConnectionSettings(pool);
    
                if (!string.IsNullOrWhiteSpace(defaultIndex))
                {
                    setting.DefaultIndex(defaultIndex);
                }
    
                if (!string.IsNullOrWhiteSpace(defaultType))
                {
                    setting.DefaultTypeName(defaultType);
                }
    
                return new ElasticClient(setting);
            }
    
            /// <summary>
            /// 如果同名索引不存在则创建索引
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="client">ElasticClient实例</param>
            /// <param name="indexName">要创建的索引名称</param>
            /// <param name="numberOfReplicas">默认副本数量,如果是单实例,注意改成0</param>
            /// <param name="numberOfShards">默认分片数量</param>
            /// <returns></returns>
            public static bool CreateIndex<T>(this ElasticClient client, string indexName = "", int numberOfReplicas = 1, int numberOfShards = 5) where T : class
            {
                if (client.IndexExists(indexName).Exists) return false;
    
                var indexState = new IndexState
                {
                    Settings = new IndexSettings
                    {
                        NumberOfReplicas = numberOfReplicas, //副本数
                        NumberOfShards = numberOfShards //分片数
                    }
                };
    
                if (string.IsNullOrWhiteSpace(indexName))
                {
                    indexName = typeof(T).Name.ToLower();
                }
    
                var result = client.CreateIndex(indexName, c => c.InitializeUsing(indexState).Mappings(ms => ms.Map<T>(m => m.AutoMap())));
                return result.Acknowledged;
            }
    
            /// <summary>
            /// 返回一个正序排列的委托
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="field"></param>
            /// <returns></returns>
            public static Func<SortDescriptor<T>, SortDescriptor<T>> Sort<T>(string field) where T : class
            {
                return sd => sd.Ascending(field);
            }
    
            public static Func<SortDescriptor<T>, SortDescriptor<T>> Sort<T>(Expression<Func<T, object>> field) where T : class
            {
                return sd => sd.Ascending(field);
            }
    
            /// <summary>
            /// 返回一个倒序排列的委托
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="field"></param>
            /// <returns></returns>
            public static Func<SortDescriptor<T>, SortDescriptor<T>> SortDesc<T>(string field) where T : class
            {
                return sd => sd.Descending(field);
            }
    
            public static Func<SortDescriptor<T>, SortDescriptor<T>> SortDesc<T>(Expression<Func<T, object>> field) where T : class
            {
                return sd => sd.Descending(field);
            }
    
            /// <summary>
            /// 返回一个Must条件集合
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public static List<Func<QueryContainerDescriptor<T>, QueryContainer>> Must<T>() where T : class 
            {
                return new List<Func<QueryContainerDescriptor<T>, QueryContainer>>();
            }
    
            public static List<Func<QueryContainerDescriptor<T>, QueryContainer>> Should<T>() where T : class
            {
                return new List<Func<QueryContainerDescriptor<T>, QueryContainer>>();
            }
    
            /// <summary>
            /// 添加Match子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field">要查询的列</param>
            /// <param name="value">要查询的关键字</param>
            /// <param name="boost"></param>
            public static void AddMatch<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                string value, double? boost = null) where T : class 
            {
                musts.Add(d => d.Match(mq => mq.Field(field).Query(value).Boost(boost)));
            }
    
            public static void AddMatch<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, string value) where T : class
            {
                musts.Add(d => d.Match(mq => mq.Field(field).Query(value)));
            }
    
            /// <summary>
            /// 添加MultiMatch子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="fields">要查询的列</param>
            /// <param name="value">要查询的关键字</param>
            public static void AddMultiMatch<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                string[] fields, string value) where T : class
            {
                musts.Add(d => d.MultiMatch(mq => mq.Fields(fields).Query(value)));
            }
    
            /// <summary>
            /// 添加MultiMatch子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="fields">例如:f=>new [] {f.xxx, f.xxx}</param>
            /// <param name="value">要查询的关键字</param>
            public static void AddMultiMatch<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts,
                Expression<Func<T, object>> fields, string value) where T : class
            {
                musts.Add(d => d.MultiMatch(mq => mq.Fields(fields).Query(value)));
            }
    
            /// <summary>
            /// 添加大于子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field">要查询的列</param>
            /// <param name="value">要比较的值</param>
            public static void AddGreaterThan<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).GreaterThan(value)));
            }
    
            public static void AddGreaterThan<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).GreaterThan(value)));
            }
    
            /// <summary>
            /// 添加大于等于子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field">要查询的列</param>
            /// <param name="value">要比较的值</param>
            public static void AddGreaterThanEqual<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).GreaterThanOrEquals(value)));
            }
    
            public static void AddGreaterThanEqual<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).GreaterThanOrEquals(value)));
            }
    
            /// <summary>
            /// 添加小于子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field">要查询的列</param>
            /// <param name="value">要比较的值</param>
            public static void AddLessThan<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).LessThan(value)));
            }
    
            public static void AddLessThan<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).LessThan(value)));
            }
    
            /// <summary>
            /// 添加小于等于子句
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field">要查询的列</param>
            /// <param name="value">要比较的值</param>
            public static void AddLessThanEqual<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).LessThanOrEquals(value)));
            }
    
            public static void AddLessThanEqual<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, double value) where T : class
            {
                musts.Add(d => d.Range(mq => mq.Field(field).LessThanOrEquals(value)));
            }
    
            /// <summary>
            /// 添加一个Term,一个列一个值
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field">要查询的列</param>
            /// <param name="value">要比较的值</param>
            public static void AddTerm<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                object value) where T : class
            {
                musts.Add(d => d.Term(field, value));
            }
    
            public static void AddTerm<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, object value) where T : class
            {
                musts.Add(d => d.Term(field, value));
            }
    
            /// <summary>
            /// 添加一个Terms,一个列多个值
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="musts"></param>
            /// <param name="field"></param>
            /// <param name="values"></param>
            public static void AddTerms<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, string field,
                object[] values) where T : class
            {
                musts.Add(d => d.Terms(tq => tq.Field(field).Terms(values)));
            }
    
            public static void AddTerms<T>(this List<Func<QueryContainerDescriptor<T>, QueryContainer>> musts, 
                Expression<Func<T, object>> field, object[] values) where T : class
            {
                musts.Add(d => d.Terms(tq => tq.Field(field).Terms(values)));
            }
        }
    }

    使用方法

    /// <summary>
            /// 搜索
            /// </summary>
            /// <param name="input"></param>
            /// <param name="pageIndex"></param>
            /// <returns></returns>
            public IActionResult Index(CourseEsSearchInput input, int pageIndex = 1)
            {
                pageIndex = pageIndex > 0 ? pageIndex : 1;
    
                //var musts = new List<Func<QueryContainerDescriptor<CourseEsDto>, QueryContainer>>();
                var musts = EsUtil.Must<CourseEsDto>();
                if (!string.IsNullOrWhiteSpace(input.School))
                {
                    //musts.Add(c => c.Term(cc => cc.Field("School").Value(input.School)));
                    musts.AddMatch("school", input.School);
                }
    
                if (!string.IsNullOrWhiteSpace(input.Key))
                {
                    //musts.Add(c => c.MultiMatch(cc => cc.Fields(ccc => ccc.Fields(ced => new[] {ced.Title, ced.School})).Query(input.Key)));
                    musts.Add(c => c.MultiMatch(cc => cc.Query(input.Key).Fields(new[] { "title", "school" })));
                }
    
                var must2 = EsUtil.Must<CourseEsDto>();
    
                if (!string.IsNullOrWhiteSpace(input.Ver1))
                {
                    //musts.Add(c => c.Term(cc => cc.Ver1, input.Ver1));
                    must2.AddTerm("ver1", input.Ver1);
                }
    
                if (!string.IsNullOrWhiteSpace(input.Ver2))
                {
                    //musts.Add(c => c.Term(cc => cc.Field(ced => ced.Ver2).Value(input.Ver2)));
                    must2.AddTerm("ver2", input.Ver2);
                }
    
                if (!string.IsNullOrWhiteSpace(input.Ver3))
                {
                    //musts.Add(c => c.Term(cc => cc.Field(ced => ced.Ver3).Value(input.Ver2)));
                    must2.AddTerm("ver3", input.Ver3);
                }
    
                if (input.PriceStart.HasValue)
                {
                    //musts.Add(c => c.Range(cc => cc.Field(ccc => ccc.Price).GreaterThan((double)input.PriceStart.Value)));
                    must2.AddGreaterThan("price", (double)input.PriceStart.Value);
                }
    
                if (input.PriceEnd.HasValue)
                {
                    //musts.Add(c => c.Range(cc => cc.Field(ccc => ccc.Price).LessThanOrEquals((double)input.PriceEnd.Value)));
                    must2.AddLessThanEqual("price", (double)input.PriceEnd.Value);
                }
    
                var client = EsUtil.Client("http://127.0.0.1:9200", "course", "doc");
                var result = client.Search<CourseEsDto>(sd =>
                    sd.Query(qcd => qcd
                            .Bool(cc => cc
                                .Must(musts)
                                .Filter(must2))
                            )
                            .From(10 * (pageIndex - 1))
                            .Take(10)
                        //.Sort(sdd => sdd.Descending("price"))
                        .Sort(EsUtil.Sort<CourseEsDto>(c => c.Price))
                );
    
                var total = result.Total;
                var data = result.Documents;
                ViewBag.Total = total;
                return View(data);
            }
    
            /// <summary>
            /// 创建索引
            /// </summary>
            /// <returns></returns>
            public IActionResult CreateIndex()
            {
                var result = EsUtil.Client("http://127.0.0.1:9200").CreateIndex<CourseEsDto>("course");
                if (result)
                {
                    return Content("创建成功");
                }
                else
                {
                    return Content("创建失败,可能已存在同名索引");
                }
            }
  • 相关阅读:
    js篇之对象数据属性与存取器属性
    使用ts-loader与webpack编译typescripts出现Module build failed: TypeError: Cannot read property 'afterCompile' of undefined
    js对象深拷贝
    前端工程化之webpack中配置babel-loader(四)
    前端工程化-webpack篇之babel-polyfill与babel-runtime(三)
    process.cwd()与__dirname的区别
    jade(pug)学习和使用
    [bzoj4033][HAOI2015]树上染色_树形dp
    [bzoj2657][Zjoi2012]旅游 journey_ 对偶图_树形dp
    [bzoj2097][Usaco2010 Dec]Exercise 奶牛健美操_贪心_树形dp_二分
  • 原文地址:https://www.cnblogs.com/diwu0510/p/11161246.html
Copyright © 2020-2023  润新知