• elasticsearch.net search入门使用指南中文版


    原文:http://edu.dmeiyang.com/book/nestusing.html


    elasticsearch.net为什么会有两个客户端?

    Elasticsearch.Net是一个非常底层且灵活的客户端,它不在意你如何的构建自己的请求和响应。它非常抽象,因此所有的Elasticsearch API被表示为方法,没有太多关于你想如何构建json/request/response对象的东东,并且它还内置了可配置、可重写的集群故障转移机制。

    Elasticsearch.Net有非常大的弹性,如果你想更好的提升你的搜索服务,你完全可以使用它来做为你的客户端。

    NEST是一个高层的客户端,可以映射所有请求和响应对象,拥有一个强类型查询DSL(领域特定语言),并且可以使用.net的特性比如协变、Auto Mapping Of POCOs,NEST内部使用的依然是Elasticsearch.Net客户端。

     NEST Client

    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; }
    }
    //懒人建站http://www.51xuediannao.com/

    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

    属性名值类型描述
    Analyzer string 分析器名称,值包含standard、simple、whitespace、stop、keyward、pattern、language、snowball、custom等,查看分析器更多信息请点击Elasticsearch Analyzers
    Boost double 加权值,值越大得分越高
    NullValue string 插入文档时,如果数据为NULL时的默认值
    Index FieldIndexOption 是否使用分析器,默认使用FieldIndexOption.Analyzed,禁止使用分析器FieldIndexOption.NotAnalyzed

    2、NumberAttribute

    属性名值类型描述
    type NumberType 构造函数参数,指定当前属性的类型,NumberType.Default、Float、Double、Integer、Long、Short、Byte
    Boost double 加权值,值越大得分越高
    NullValue double 插入文档时,如果数据为NULL时的默认值

    3、BooleanAttribute

    属性名值类型描述
    Boost double 加权值,值越大得分越高
    NullValue double 插入文档时,如果数据为NULL时的默认值

    4、DateAttribute

    属性名值类型描述
    Boost double 加权值,值越大得分越高
    NullValue string 插入文档时,如果数据为NULL时的默认值
    Format string  

    5、ObjectAttribute

    属性名值类型描述
    type string/Type 构造函数参数,指定当前属性的类型T
    Dynamic DynamicMapping  

     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("俏佳人"))
            )
        )
    );
    //c#教程http://www.51xuediannao.com/c_asp_net/

    注意:

    如果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("历史小河")));
    

    4、过滤作者等于“历史小河”或者等于“友谊的小船”的文档,匹配多个作者中间用空格隔开

    query.PostFilter(x => x.QueryString(t => t.Fields(f => f.Field(obj => obj.Author)).Query("历史小河 友谊的小船")));
    

    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>();
    client.IndexMany<Student>(list);
    

    二、局部更新单一文档及批量操作

    局部更新单一文档

    client.Update<Student, object>("002", upt => upt.Doc(new { Name = "江山美人" }));
    

    局部更新批量文档

    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 = "胡一刀" };
        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);
    
    本文链接:elasticsearch.net search入门使用指南中文版(翻译)http://www.51xuediannao.com/c_asp_net/elasticsearch_net.html
  • 相关阅读:
    阿里云 CDN+OSS 解决方案
    一次完整的HTTP请求过程
    apache多站点配置中ServerAlias什么意思
    legend3---apache配置https
    legend3---Fiddler如何抓手机app的包
    Fiddler:增加IP列
    http请求报文格式和响应报文格式
    http请求头中Referer的含义和作用
    Chrome保存的HAR文件怎么打开
    Android Studio 错误 Duplicate files copied in APK META-INF/LICENSE.txt
  • 原文地址:https://www.cnblogs.com/lisengl/p/6134079.html
Copyright © 2020-2023  润新知