【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("创建失败,可能已存在同名索引");
            }
        }

原文地址:https://www.cnblogs.com/diwu0510/p/11161246.html

时间: 2024-10-29 19:37:26

【ElasticSearch+NetCore 第二篇】Nest封装的相关文章

ElasticSearch入门 第一篇:Windows下安装ElasticSearch

https://www.elastic.co/downloads/past-releases/elasticsearch-2-4-4 这是ElasticSearch 2.4 版本系列的第一篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 ElasticSearch入门 第三篇:索引 ElasticSearch入门 第四篇:使用C#添加和更新文档 ElasticSearch入门 第五篇:使用C#查询文档

第二篇 基于微擎的模块开发—PHP

从陌生到如今能勉强完成第一个微网站模块的实现.也算是一个小小的进步,从设计数据库到,返回数据,前端模版渲染 每一点都是有点难度的.所以我想总结一下,我是如何实现一个微擎模块. 第一,首先得分析某个模块的想实现什么需求,根据需求设计合理的数据库结构. 第二,了解微擎的结构,运行流程,设计模块结构. 第三,重点就是site.php , 完成site.php 需要一定的php的编程能力, 第四,site.php 其中 通过 pdo 从数据库的获取我们想得到数据源. 微擎已封装其路由机制, doWeb

Cocos2d-x3.0游戏实例之《别救我》第二篇——创建物理世界

这篇我要给大家介绍两个知识点: 1. 创建游戏物理世界 2. 没了(小若:我噗) 害怕了?不用担心,这太简单了~! 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址:http://www.benmutou.com/blog/archives/804 文章来源:笨木头与游戏开发 3.0新亮点,史上最简单的物理引擎 在Cocos2d-x3.0里使用物理引擎,会很有快感,因为很多繁琐的东西它都帮我们封装好了. 那么,我要开始创建游戏的关卡场景了,大家跟紧了. 我们给关卡场景命名为Toll

Web前端学习第二篇

今天看到了一篇写的不错的文章,是有关对JQuery.js等一些源代码初识的内容,感觉写的还是不错,所以拿过来分享一下. 文章的地址:http://my249645546.iteye.com/blog/1716629 1.对(function(){})(); 几乎所有的开源js代码开篇都是这样(function(……){……})(……); 下面是Jquery的部分源码: (function( window, undefined ) { var jQuery = function( selector

js面向对象编程:this到底代表什么?第二篇

总认为自己弄明白了js中this的含义,this总是指向调用方法的对象,作为方法调用,那么this就是指实例化的对象.但前几天自己写脚本却遇到了一个很奇怪的问题. 代码如下: //内部对象AutoCompleteInner function AutoCompleteInner(transformResultInner) { if(transformResultInner) { this.transformResultInner=transformResultInner; } } AutoComp

针对 ElasticSearch .Net 客户端的一些封装

ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便. ElasticSearch 为.net提供了两个客户端,分别是 Elasticsearch.Net  和  NEST Elasticsearch.net为什么会有两个客户端?

prometheus监控第二篇之grafana

prometheus监控第二篇 ??1. 使用prometheus监控kube-state-metrics ??上篇博文我们已经成功安装了prometheus.并且使用prometheus成功监控了redis应用.同时使用prometheus监控了kubernetes-service-endpoints.kubernetes-nodes.kubernetes-kubelet.kubernetes-cadvisor.kubernetes-apiserveres等.现在开始使用prometheus监

Spring Cloud第二篇 | 使用并认识Eureka注册中心

? 本文是Spring Cloud专栏的第二篇文章,了解前一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 ?? 一.SpringCloud快速开发入门 SpringCloud是构建在SpringBoot基础之上的 1.创键一个服务提供者(springcloud-service-provider) 1-1.创键提供者类 @RestController @RequestMapping("/provider") pub

使用docker部署tomcat|tomcat基础使用第二篇

使用docker部署tomcat|tomcat基础使用第二篇 1. review tomcat服务器学习:https://www.cnblogs.com/jiading/p/11974935.html docker学习:https://www.cnblogs.com/jiading/p/12131441.html 2. tomcat使用补充 tomcat服务器的文件位置在哪里 今天猛然间发现之前配置的tomcat居然是随机启动的,也就是说它一直在默默运行着2333,幸好内存占用不大.不过这也从侧