再次强调,我安装的Elasticsearch 版本是 7.8.0 ,C# 操作 Elasticsearch 的驱动有 NEST、Elasticsearch.net 、PlainElastic.Net 等,当然要注意版本是否匹配,

PlainElastic.Net 是比较旧的操作 Elasticsearch 的方式 ,但是看到不少园友用这个,所以本篇也用 PlainElastic.Net ,稍后有时间会给出 NEST 、 Elasticsearch.net 的 Demo

PlainElastic.Net 的参考文档、使用方法可以看 https://github.com/Yegoroff/PlainElastic.Net

完整的 Demo 见 https://github.com/fhrddx/ES_Query ,前端 UI 框架是 aceadmin ,见 http://ace.jeka.by/

先看一下效果图

1、首先是封装 ElasticSearchHelper

    public class ElasticSearchHelper
{
public static readonly ElasticSearchHelper Intance = new ElasticSearchHelper(); private ElasticConnection Client; private ElasticSearchHelper()
{
Client = new ElasticConnection("localhost", );
}
}

2、在 ElasticSearchHelper 设定字段mapping 并生成索引库  db_student_test1

    public bool BuildStudentMapping()
{
var mapping = new
{
mappings = new
{
properties = new
{
name = new
{
type = "text",
analyzer = "standard"
},
school = new
{
type = "text",
analyzer = "ik_max_word"
},
desc = new
{
type = "text",
analyzer = "ik_max_word"
},
@class = new
{
type = "integer"
},
chinese = new
{
type = "integer"
},
english = new
{
type = "integer"
},
math = new
{
type = "integer"
}
}
}
};
string jsonDocument = new JsonNetSerializer().Serialize(mapping);
OperationResult operationResult = Client.Put("db_student_test1", jsonDocument);
CommandResult result = new JsonNetSerializer().ToCommandResult(operationResult.Result);
if (result?.acknowledged != null)
return result.acknowledged;
return false;
}

3、在 ElasticSearchHelper中,给与索引库  db_student_test1 一个别名  student_test1

        public bool Alias()
{
OperationResult operationResult = Client.Put("db_student_test1/_alias/student_test1");
CommandResult result = new JsonNetSerializer().ToCommandResult(operationResult.Result);
if (result?.acknowledged != null)
return result.acknowledged;
return false;
}

4、创建索引文档

        public IndexResult CreateIndex(string indexName, string id, string jsonDocument)
{
var serializer = new JsonNetSerializer();
//注意ES版本是8.7.0,type只能是默认的、唯一的 _doc
string cmd = new IndexCommand(indexName, "_doc", id);
Client.Timeout = ;
OperationResult result = Client.Put(cmd, jsonDocument);
var indexResult = serializer.ToIndexResult(result.Result);
return indexResult;
} public IndexResult CreateIndex(string indexName, string id, object document)
{
var serializer = new JsonNetSerializer();
var jsonDocument = serializer.Serialize(document);
return CreateIndex(indexName, id, jsonDocument);
}

5、随机生成测试数据,网上下载一篇txt的长篇小说,随机截取字段,然后写入Elasticsearch

测试数据如下:

    public class TestData
{
public static string xing = @"王李张刘陈杨赵黄周吴徐孙胡朱高林何郭马罗梁宋郑谢韩唐冯于董萧程曹袁邓许傅沈曾彭吕苏卢蒋蔡贾丁魏薛叶阎余潘杜戴夏钟汪田任姜范方石姚谭廖邹熊金陆郝孔白崔康毛邱秦江史顾侯邵孟龙万段雷钱汤尹黎易常武乔贺赖龚文庞樊兰殷施陶洪翟安颜倪严牛温芦季俞章鲁葛伍韦申尤毕聂丛焦向柳邢路岳齐沿梅莫庄辛管祝左涂谷祁时舒耿牟卜肖詹关苗凌费纪靳盛童欧甄项曲成游阳裴席卫查屈鲍位覃霍翁隋植甘景薄单包司柏宁柯阮桂闵欧阳解强柴华车冉房边净阴闫佘练骆付代麦容悲初瞿褚班全名井米谈宫虞奚佟符蒲穆漆卞东储党从艾苻厉岑燕吉冷仇伊首郁娄楚邝历狄简胥连帅封危支原滕苑信索栗官沙池藏师国巩刁茅杭巫居窦皮戈麻饶习巴旷宗荆荣孝蔺廉员西寇刃见底区郦卓琚续朴蒙敖花应喻冀尚顿菅嵇雒弓忻权谌卿扈海冼伦鹿宿山桑裘达么智宣尉迟东方幺郎农戚屠楼步鞠仲尉蓝招攀栾籍寿邬荚税逄加勾由福缑钦鲜于但邸逢况鄢古乐斯钮盖旦毅邰哈鄂商英迟仝亓玄黑腾晏禹诸苟湛殳亢奉占闻粟种匡宾劳申屠伏过水真宇巢计羌相辜展丑银丰矫上昝绳臧舍郅布糜乌衣来恒那满门司徒皋旺公言藤释尧缪干阚靖渠契晋六束良鹗贝邴沃竺扬励归上官荃焉多都果郜隆诸葛令狐慕礼祖翦力朗撖修呼富明站虢冶茹禚笪云肇平弋候尔姬宝畅冒邾延禅浦敬颉南巍补"; public static string name = @"帆栋祜权锟坤允骞谛初盛炳初泽荣喆恒鹤礼华帝宇中鑫彬槐禧允翱鹏皓中伟炳皓槐帆芃欣鑫振杰诚锟潍吉轩福宇初柏芃翰浩峰延帆欣帆奇郁烁卓仕吉帝潍钊杰鑫星谛鑫铭锋沛芃泽禄勇峰欣延鹤郁信侠翰邦寅轩泽哲佑福翱恒文枫澄栋翰中震杞斌凯锦升逸延腾谛权盛弘烁俊强博禄中欣权浩阳裕延盛平畅沛吉强骏起华炳腾柏佑畅杰凯鸿斌加振晨沛祥祜盛濡彬成弘天福锦颖嘉茜芸格美漫慧漫妍钰琪玥沛玥鑫洁岚采曼珍雪昕婷碧弦雪洁馨昕香弦帆芳菲楠俊月珊函蔚帆灵灵莲优蔚碧文蕾娅林婧妮婷薇馨淑惠杉美栀怡薇琪曦云漫瑶韵楠妮颖妮杉媛诗芳菲锦锦蕾芸欢珍岚鹤莉优云舒舒璇慧依菡雅妍楠雅慧灵阳漫珠帆媛可雅欣鑫妮雯霞柔芳芝琳彩冰林媛柔初倩玉冰薇洁妍洁璐采彩颖呈雪云欢琪璟紫静蓓薇欢薇柔晨萱云歆鑫月阳娅媛露露琳"; public static string[] school = new string[] { "中山大学", "暨南大学", "汕头大学", "华南理工大学", "华南农业大学", "广东海洋大学", "广州医科大学", "广州中医药大学", "华南师范大学", "韶关学院", "深圳大学", "广东财经大学", "广东工业大学", "东莞理工学院", "南方科技大学", "香港中文大学", "广州商学院", "上海交通大学", "同济大学", "复旦大学", "上海大学", "上海财经大学", "北京大学", "清华大学", "北京邮电大学", "中国人民大学", "北京理工大学" }; public static string content = @"第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀() 此开卷第一回也.作者自云:因曾历过一番梦幻之后,故将真事隐去,而借”通灵”之说,撰此《石头记》一书也.故曰”甄士隐”云云.但书所记何事何人?自又云:“今风尘碌碌,一事无成,忽念及当日所有之女子,一一细考较去,觉其行止见识,皆出于我之上.何我堂堂须眉,诚不若彼裙钗哉?实愧则有余,悔又无益之大无可如何之日也!当此,则自欲将已往所赖天恩祖德,锦衣纨绔之时,饫甘餍肥之日,背父兄教育之恩,负师友规谈之德,以至今日一技无成,半生潦倒之罪,编述一集,以告天下人:我之罪固不免,然闺阁本自历历有人,万不可因我之不肖,自护己短,一并使其泯灭也.虽今日之茅椽蓬牖,瓦灶绳床,其晨夕风露,阶柳庭花,亦未有妨我之襟怀笔墨者.虽我未学,下笔无,又何妨用假语村言,敷演出一段故事来,亦可使闺阁昭传,复可悦世之目,破人愁闷,不亦宜乎?”故曰”贾雨村”云云.
......
......
由来同一梦,休笑世人痴!";
}

随机生成学生记录的代码如下:

            int xing_length = TestData.xing.Length;
int name_length = TestData.name.Length;
int school_length = TestData.school.Length;
int content_length = TestData.content.Length; ParallelOptions _po = new ParallelOptions();
_po.MaxDegreeOfParallelism = ;
Parallel.For(, , _po, c =>
{
Random r = new Random(c);
Random r2 = new Random();
try
{
string desc = TestData.content.Substring((r.Next(, content_length - )), ).Trim().Replace("/r/n", string.Empty);
Student model = new Student()
{
name = TestData.xing[r.Next(, xing_length)].ToString() + TestData.name.Substring(r.Next(, name_length / ) * , ),
school = TestData.school[r.Next(, school_length)],
chinese = r.Next(, ) + r2.Next(, ),
math = r.Next(, ) + r2.Next(, ),
english = r.Next(, ) + r2.Next(, ),
@class = c,
desc = desc + TestData.school[r2.Next(, school_length)]
};
ElasticSearchHelper.Intance.CreateIndex("db_student_test1", Guid.NewGuid().ToString(), model);
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
});

6、单个词语查询,例如查询满足以下条件的文档:(1) desc 包含 “黛玉” (2)chinese、math、english 都大于90(3)分页取前10条记录(4)关键词高亮(5)排序按照语文、数学、英语倒序

controller 代码如下

        public ActionResult Index(string key = "黛玉")
{
Stopwatch sw = new Stopwatch();
sw.Restart();
var model = ElasticSearchHelper.Intance.Term(key.Trim(), , );
sw.Stop();
ViewBag.Message = $"共耗时{sw.ElapsedMilliseconds}毫秒";
return View(model);
}

ElasticsearchHelper 代码如下

        public ElasticsearchResult<Student> Term(string key, int from = , int size = )
{
if (string.IsNullOrEmpty(key))
return null; key = key.Trim();
string cmd = new SearchCommand("student_test1", "_doc");
var query = new QueryBuilder<Student>().Query(
b => b.Bool(m => m.Must(t =>
t.Term(d => d.Field("desc").Value(key))
.Range(d => d.Field("chinese").From("").To(""))
.Range(d => d.Field("math").Gt(""))
.Range(d => d.Field("english").Gt(""))
)
)
)
.From(from)
.Size(size)
.Sort(s => s.Field("chinese", SortDirection.desc).Field("math", SortDirection.desc).Field("english", SortDirection.desc))
.Highlight(h => h
.PreTags("<span class=\"label label-sm label-danger\">")
.PostTags("</span>")
.Fields(
f => f.FieldName("desc").Order(HighlightOrder.score)
)
)
.Build(); string result = Client.Post(cmd, query);
var list = new JsonNetSerializer().Deserialize<ElasticsearchResult<Student>>(result);
return list;
}

效果是

7、语句匹配查询,关键词是“黛玉”,当然是可以查出来,但是如果用户知道红楼梦有个情节,是关于大观园里众人举办螃蟹宴,作诗玩乐的,想把相关文段查询出来,这时用户输入的关键词是 “宝玉黛玉螃蟹宴作诗” ,这时候会查询出什么呢?

首先改一下逻辑,controller 代码为

       public ActionResult Query(string key = "宝玉黛玉螃蟹宴作诗")
{
Stopwatch sw = new Stopwatch();
sw.Restart();
var model = ElasticSearchHelper.Intance.Query(key.Trim(), , );
sw.Stop();
ViewBag.Message = $"共耗时{sw.ElapsedMilliseconds}毫秒";
return View("~/Views/ES/Index.cshtml", model);
}

ElasticsearchHelper 代码如下

        public ElasticsearchResult<Student> Query(string key, int from = , int size = )
{
if (string.IsNullOrEmpty(key))
return null; key = key.Trim();
string cmd = new SearchCommand("student_test1", "_doc");
var query = new QueryBuilder<Student>().Query(
b => b.Bool(m => m.Must(t =>
//其实也是可以用 t.match() 的,可以试一下
t.QueryString(d => d.DefaultField("desc").Query(key))
.Range(d => d.Field("chinese").From("").To(""))
.Range(d => d.Field("math").Gt(""))
.Range(d => d.Field("english").Gt(""))
)
)
)
.From(from)
.Size(size)
//这里不再按照分数来排序,这时ES会根据关键词匹配度来排序,出现在最前的,应该是最匹配的
//.Sort(s => s.Field("chinese", SortDirection.desc).Field("math", SortDirection.desc).Field("english", SortDirection.desc))
.Highlight(h => h
.PreTags("<span class=\"label label-sm label-danger\">")
.PostTags("</span>")
.Fields(
f => f.FieldName("desc").Order(HighlightOrder.score)
)
)
.Build(); string result = Client.Post(cmd, query);
var list = new JsonNetSerializer().Deserialize<ElasticsearchResult<Student>>(result);
return list;
}

查询结果是

可以看到,ES 会把  “宝玉黛玉螃蟹宴作诗” 进行分词,然后进行文本匹配。

PlainElastic.Net 是比较旧的版本了,不是很适合ES版本 7.8.0 可以用 NEST 或者 Elasticsearch.net ,我这里是参考一些园友,然后写个Demo出来测试一下。

(未完,ES 聚合统计的,待续)

Elasticsearch第五篇:PlainElastic.Net 操作 Elasticsearch的更多相关文章

  1. elasticsearch 第五篇(文档操作接口)

    INDEX API 示例: 1 2 3 4 5 PUT /test/user/1 { "name": "silence", "age": 2 ...

  2. ElasticSearch(五):Java操作ElasticSearch执行查询

    package com.gxy.ESChap01; import java.net.InetAddress; import org.elasticsearch.action.search.Search ...

  3. Elasticsearch入门系列~通过Java一系列操作Elasticsearch

    Elasticsearch索引的创建.数据的增删该查操作 上一章节已经在Linux系统上安装Elasticsearch并且可以外网访问,这节主要通过Java代码操作Elasticsearch 1.创建 ...

  4. R学习笔记 第五篇:字符串操作

    文本数据存储在字符向量中,字符向量的每个元素都是字符串,而非单独的字符.在R中,可以使用双引号,或单引号表示字符,函数nchar用于获得字符串中的字符数量: > s='read' > nc ...

  5. ElasticSearch(七):Java操作elasticsearch基于smartcn中文分词查询

    package com.gxy.ESChap01; import java.net.InetAddress; import org.elasticsearch.action.search.Search ...

  6. ElasticSearch(三):Java操作ElasticSearch索引之CRUD

    package com.gxy.ESChap01; import java.net.InetAddress; import java.util.HashMap; import java.util.Ma ...

  7. R语言学习 第五篇:字符串操作

    文本数据存储在字符向量中,字符向量的每个元素都是字符串,而非单独的字符.在R中,可以使用双引号,或单引号表示字符. 一,字符串中的字符数量 函数nchar()用于获得字符串中的字符数量: > s ...

  8. ElasticSearch(五):简单的ElasticSearch搜索功能

    这里主要是一些简单的ElasticSearch的搜索功能,复杂的搜索,比如过滤,聚合等以后单独在写 1. 搜索全部 GET book/_search 直接搜索全部,下面是对搜索结果的详细介绍:默认情况 ...

  9. 第十五篇:java操作oracle踩坑之旅

    最近刚做完mysql的各种需求,项目要满足oracle数据库,于是走上了漫漫的踩坑之路,同行可以看看以免踩坑……第一条:oracle建表的时候不需要在建表sql语句后指定默认字符集 DEFAULT C ...

随机推荐

  1. IDM的“免费版”NDM免费的下载工具

    软件截图 软件介绍 免费小巧的多线程下载工具,支持断点续传,支持浏览器扩展,嗅探下载音视频文件. 和IDM差不多,只不过是免费的 下载软件 Win 我提供的UCloud-OSS 官网下载 Mac 我提 ...

  2. SparkCore

    一.概述 1,定义 RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象.代码中是一个抽象类,它代表一个不可变.可分区.里面的元素可 ...

  3. java opencsv解析csv文件

    记一次使用opencsv解析csv文件时碰到的坑 最近在开发过程中需要解析csv文件,公司用的解析工具是opencsv,在根据opencsv的官方文档去解析时发现csv文件中含有繁体字,使用其自带的C ...

  4. xilinx fpga中块ram的使用——简单双端口ram的使用

    在简单双端口ram中最简单有9个端口:分别是 clka  为输入端口的时钟 wea  读写控制端,高为写,低为读 addra 写地址 dina  待写入的数据 clkb 为输出端口的时钟的 addrb ...

  5. Python过滤掉numpy.array中非nan数据实例

    代码 需要先导入pandas arr的数据类型为一维的np.array import pandas as pd arr[~pd.isnull(arr)] 补充知识:python numpy.mean( ...

  6. 学习2周C++的收获

    学习2周C++的收获 首先,C++是一种实用性很强的程序设计语言.它使用起来灵活.方便,运算符丰富,有结构化的层次…… 那么,我学习这个语言主要是为了参加信息学奥林匹克竞赛,这不仅要熟练地掌握一门语言 ...

  7. Redis的持久化之RDB

    1.什么是Redis的持久化 Redis是一种高级key-value数据库,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,所以Redis的所有数据都 ...

  8. 想学Python不知道从哪里开始学?|百度网盘免费下载| 这本入门书了解下

    百度网盘免费下载:编程小白的第一本 Python 入门书 提取码:s0pc Python是什么 Python是一种计算机程序设计语言,由吉多·范罗苏姆创造,第一版发布于1991年,可以视之为一种改良的 ...

  9. scrapyd 部署

    步骤 1 pip install scrapyd pip install scrapy-client 步骤 2 修改 scrapy.cfg [deploy:targetName]url = http: ...

  10. Django开发之Datetime类型JSON序列化时报错

    前提回顾 在进行django开发view视图时,如果数据库字段是 datetime类型,在JSON序列化返回时,会出现异常 异常现象 TypeError: Object of type datetim ...