您好,欢迎访问一九零五行业门户网

C#如何使用ES

elasticsearch简介
elasticsearch (es)是一个基于 lucene 的开源搜索引擎,它不但稳定、可靠、快速,而且也具有良好的水平扩展能力,是专门为分布式环境设计的。
elasticsearch是什么
elasticsearch是一个基于apache lucene(tm)的开源搜索引擎,无论在开源还是专有领域,lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。 
但是,lucene只是一个库。想要发挥其强大的作用,你需使用c#将其集成到你的应用中。lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。 
elasticsearch也是使用java编写并使用lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的restful api让全文搜索变得简单并隐藏lucene的复杂性。 
不过,elasticsearch不仅仅是lucene和全文搜索引擎,它还提供:
分布式的实时文件存储,每个字段都被索引并可被搜索
实时分析的分布式搜索引擎
可以扩展到上百台服务器,处理pb级结构化或非结构化数据
而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的restful api、各种语言的客户端甚至命令行与之交互。上手elasticsearch非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。elasticsearch在apache 2 license下许可使用,可以免费下载、使用和修改。 
随着知识的积累,你可以根据不同的问题领域定制elasticsearch的高级特性,这一切都是可配置的,并且配置非常灵活。
使用c#操作es
nest是一个高层的客户端,可以映射所有请求和响应对象,拥有一个强类型查询dsl(领域特定语言),并且可以使用.net的特性比如协变、auto mapping of pocos,nest内部使用的依然是elasticsearch.net客户端。elasticsearch.net(nest)客户端提供了强类型查询dsl,方便用户使用,源码下载。
一、如何安装nest
打开vs的工具菜单,通过nuget包管理器控制台,输入以下命令安装nest
install-package nest
安装后引用了以下三个dll
elasticsearch.net.dll(2.4.4)nest.dll(2.4.4)newtonsoft.json.dll(9.0版本)
二、链接elasticsearch
你可以通过单个节点或者指定多个节点使用连接池链接到elasticsearch集群,使用连接池要比单个节点链接到elasticsearch更有优势,比如支持负载均衡、故障转移等。
通过单点链接:
var node = new uri(http://myserver:9200);
var settings = new connectionsettings(node);
var client = new elasticclient(settings);
通过连接池链接:
var nodes = new uri[]
{
    new uri(http://myserver1:9200),
    new uri(http://myserver2:9200),
    new uri(http://myserver3:9200)
};
var pool = new staticconnectionpool(nodes);
var settings = new connectionsettings(pool);
var client = new elasticclient(settings);
nest index
为了知道请求需要操作哪个索引,elasticsearch api期望收到一个或多个索引名称作为请求的一部分。
一、指定索引
1、可以通过connectionsettings使用.defaultindex(),来指定默认索引。当一个请求里没有指定具体索引时,nest将请求默认索引。
var settings = new connectionsettings()
.defaultindex(defaultindex);
2、可以通过connectionsettings使用.mapdefaulttypeindices(),来指定被映射为clr类型的索引。
var settings = new connectionsettings()
.mapdefaulttypeindices(m => m
.add(typeof(project), projects)
  );
注意:通过.mapdefaulttypeindices()指定索引的优先级要高于通过.defaultindex()指定索引,并且更适合简单对象(poco)
3、另外还可以显示的为请求指定索引名称,例如:
var response = client.index(student, s=>s.index(db_test));
var result = client.search<student>(s => s.index(db_test));
var result = client.delete<student>(null, s => s.index(db_test));
注意:当现实的为请求指定索引名称时,这个优先级是最高的,高于以上两种方式指定的索引。
4、一些elasticsearch api(比如query)可以采用一个、多个索引名称或者使用_all特殊标志发送请求,请求nest上的多个或者所有节点
//请求单一节点
var singlestring = nest.indices.index(db_studnet);
var singletyped = nest.indices.index<student>();
isearchrequest singlestringrequest = new searchdescriptor<student>().index(singlestring);
isearchrequest singletypedrequest = new searchdescriptor<student>().index(singletyped);
//请求多个节点
var manystrings = nest.indices.index(db_studnet, db_other_student);
var manytypes = nest.indices.index<student>().and<otherstudent>();
isearchrequest manystringrequest = new searchdescriptor<student>().index(manystrings);
isearchrequest manytypedrequest = new searchdescriptor<student>().index(manytypes);
//请求所有节点
var indicesall = nest.indices.all;
var allindices = nest.indices.allindices;
isearchrequest indicesallrequest = new searchdescriptor<student>().index(indicesall);
isearchrequest allindicesrequest = new searchdescriptor<student>().index(allindices);
二、创建索引
elasticsearch api允许你创建索引的同时对索引进行配置,例如:
var descriptor = new createindexdescriptor(db_student)
.settings(s => s.numberofshards(5).numberofreplicas(1));
client.createindex(descriptor);
这里指定了该索引的分片数为5、副本数为1。
三、删除索引
elasticsearch api允许你删除索引,例如:
var descriptor = new deleteindexdescriptor(db_student).index(db_student);
client.deleteindex(descriptor)
这里制定了要删除的索引名称“db_student”,以下为更多删除用例:
//删除指定索引所在节点下的所有索引
var descriptor = new deleteindexdescriptor(db_student).allindices();
nest mapping
nest提供了多种映射方法,这里介绍下通过attribute自定义映射。
一、简单实现
1、定义业务需要的poco,并指定需要的attribute
[elasticsearchtype(name = student)]
public class student
{
    [nest.string(index = fieldindexoption.notanalyzed)]
    public string id { get; set; }
[nest.string(analyzer = standard)]
    public string name { get; set; }
[nest.string(analyzer = standard)]
    public string description { get; set; }
public datetime datetime { get; set; }
}
2、接着我们通过.automap()来实现映射
var descriptor = new createindexdescriptor(db_student)
    .settings(s => s.numberofshards(5).numberofreplicas(1))
    .mappings(ms => ms
        .map<student>(m => m.automap())
    );
client.createindex(descriptor);
注意:通过.properties()可以重写通过attribute定义的映射
二、attribute介绍
1、stringattribute
2、numberattribute
3、booleanattribute
4、dateattribute
5、objectattribute
nest search
nest提供了支持lambda链式query dls(领域特定语言)方式,以下是简单实现及各个query的简述。
一、简单实现
1、定义searchdescriptor,方便项目中复杂业务的实现
var query = new nest.searchdescriptor<models.esobject>();
var result = client.search<student>(x => query)
2、检索title和content中包含key,并且作者不等于“俏佳人”的文档
query.query(q =>
    q.bool(b =>
        b.must(m =>
            m.multimatch(t => t.fields(f => f.field(obj => obj.title).field(obj => obj.content)).query(key))
        )
        .mustnot(m =>
            m.querystring(t => t.fields(f => f.field(obj => obj.author)).query(wenli))
        )
    )
);
注意:
如果elasticsearch使用默认分词,title和content的attribute为[nest.string(analyzer = standard)]
如果elasticsearch使用的是ik分词,title和content的attribute为[nest.string(analyzer = ikmaxword)]或者[nest.string(analyzer = ik_smart)]
author的attribute为[nest.string(index = fieldindexoption.notanalyzed)],禁止使用分析器
3、过滤作者等于“历史小河”的文档
query.postfilter(x => x.term(t => t.field(obj => obj.author).value(wenli)));
4、过滤作者等于“历史小河”或者等于“友谊的小船”的文档,匹配多个作者中间用空格隔开
query.postfilter(x => x.querystring(t => t.fields(f => f.field(obj => obj.author)).query(wenli yswenli)));
5、过滤数量在1~100之间的文档
query.postfilter(x => x.range(t => t.field(obj => obj.number).greaterthanorequals(1).lessthanorequals(100)));
6、排序,按照得分倒叙排列
query.sort(x => x.field(_score, nest.sortorder.descending));
7、定义高亮样式及字段
query.highlight(h => h
    .pretags(<b>)
    .posttags(</b>)
    .fields(
        f => f.field(obj => obj.title),
        f => f.field(obj => obj.content),
        f => f.field(_all)
    )
);
8、拼装查询内容,整理数据,方便前段调用
var list = result.hits.select(c => new models.esobject()
{
    id = c.source.id,
    title = c.highlights == null ? c.source.title : c.highlights.keys.contains(title) ? string.join(, c.highlights[title].highlights) : c.source.title, //高亮显示的内容,一条记录中出现了几次
    content = c.highlights == null ? c.source.content : c.highlights.keys.contains(content) ? string.join(, c.highlights[content].highlights) : c.source.content, //高亮显示的内容,一条记录中出现了几次
    author = c.source.author,
    number = c.source.number,
    isdisplay = c.source.isdisplay,
    tags = c.source.tags,
    comments = c.source.comments,
    datetime = c.source.datetime,
})
二、query dsl介绍
待整理……
elasticsearch.net document
文档操作包含添加/更新文档、局部更新文档、删除文档及对应的批量操作文档方法。
一、添加/更新文档及批量操作
添加/更新单一文档
client.index(student);
批量添加/更新文档
var list = new list<student>();2 3 client.indexmany<student>(list);
二、局部更新单一文档及批量操作
局部更新单一文档
client.update<student, object>(002, upt => upt.doc(new { name = wenli }));
局部更新批量文档
var ids = new list<string>() { 002 };
var bulkquest = new bulkrequest() { operations = new list<ibulkoperation>() };
foreach (var v in ids)
{
    var operation = new bulkupdateoperation<student, object>(v);
operation.doc = new { name = wenli };
bulkquest.operations.add(operation);
}
var result = client.bulk(bulkquest);
三、删除文档及批量操作
删除单一文档
client.delete<student>(001);
批量删除文档
var ids = new list<string>() { 001, 002 };
var bulkquest = new bulkrequest() { operations = new list<ibulkoperation>() };
foreach (var v in ids)
{
    bulkquest.operations.add(new bulkdeleteoperation<student>(v));
}
var result = client.bulk(bulkquest);
更多c#如何使用es。
其它类似信息

推荐信息