• .Net Core中使用ElasticSearch(二)


      .Net的ElasticSearch 有两个版本,Elasticsearch.Net(低级) 和 NEST(高级),推荐使用 NEST,低级版本的更灵活,水太深 把握不住。有个需要注意,使用的版本号必须要ElasticSearch服务端版本号一致。

    一、 连接池

      1.1 SingleNodeConnectionPool 单节点连接池

        适合只有一个节点的情况。当没有在ConnectionSettings 构造函数中显式指定连接池类型的时候,默认此连接池。这种连接池不会标记节点是否存活

      1.2 StaticConnectionPool 静态连接池

        适合多个节点,它维护一个静态的节点hosts清单,使用前通过ping节点来确认节点是否存活。如果一个节点处理请求失败,该节点会被标记为死节点,这个节点会被“关禁闭”,“关禁闭”出来后,会再次处理请求,如果还是失败,“关禁闭”的时间会更长。

      1.3 SniffingConnectionPool 嗅探连接池

        它继承至静态连接池,有静态连接池的Ping特性。区别在于是动态的,用户提供hosts种子,而客户端则会嗅探这些hosts并发现集群的其他节点。当集群中添加或删除节点时,客户端会相应更新。

      1.4 StickyConnectionPool 黏性连接池

        选择一个可用节点作为请求主节点,支持ping 不支持嗅探

      1.5 StickySniffingConnectionPool 黏性嗅探连接池

        选择一个可用节点作为请求主节点,支持ping 支持嗅探

    二、注入

       官方推荐使用单例注入ElasticClient。

                services.AddSingleton<IElasticClient>(provider =>
                {
                    var connectionPool = new SingleNodeConnectionPool(new Uri("http://127.0.0.1:9200"));
                    var connectionSetting = new ConnectionSettings(connectionPool).DisableDirectStreaming();
                    return new ElasticClient(connectionSetting);
                });              

    三、增删改查

    3.1 添加

    3.1.1 单个添加

    var user = new User()
    {
        Id = 1,
        Age = 18,
        Name = "MicroHeart",
        Gender = true
    };
    //第一种
    var resp = client.Index(user, s => s.Index(indexName));//指定操作索引名称 //第二种 connectionSettings.DefaultIndex(indexName);//指定默认索引名称 var client = new ElasticClient(connectionSettings); resp = client.IndexDocument(user);//操作默认索引

    3.1.2 批量添加

    //第一种
    var resp = client.IndexMany(new List<User>() { user }); //操作默认索引
    resp = client.IndexMany(new List<User>() { user }, indexName); //操作指定索引
    //第二种
    resp = client.Bulk(b => b.Index(indexName).IndexMany(users, (desc, user) => desc.Index(user.Gender ? "boy" : "girl")));
    //第三种
    var bulkAllObservable = client.BulkAll(users, b => b
                                .Index("people")
                                .BackOffTime("30s") //重试间隔时间
                                .BackOffRetries(2)  //重试次数
                                .RefreshOnCompleted()
                                .MaxDegreeOfParallelism(Environment.ProcessorCount)
                                .Size(1000) //每次请求文档个数
                            );

    IndexMany:是在单个 HTTP 请求所有文档,因此对于非常大的文档集合,这不是建议的方法。

    Bulk:是在单个 HTTP 请求所有文档,如果需要对很多文档进行索引控制,可以使用此方法。例子中将男孩插入“boy”索引中,女孩添加到“girl”索引中

    BulkAll:适合对多个大文档集合操作,在多个HTTP请求中,分批次操作文档,内置了重试机制。

    上面所有的插入方法都是根据_id的值判断文档是否存在(这里因为user有个属性为Id,默认Es将Id的属性值作为_id的值),如果已经存在文档,就更新,否则就添加。

    通过返回对象的IsValid属性来判断是否添加成功。

    3.2 删除

    var resp = client.Delete<User>(1, d => d.Index(indexName));//单个删除
    var resp = client.DeleteByQuery<User>(x => x.Index(indexName).Query(q => q.Range(r => r.Field(f => f.Age).LessThan(18)))); //删除年龄小于18的

    返回的对象包含

    deleted:表示删除的数量。 

    Failures:删除失败的集合。

    3.3 查询

    3.3.1 根据Id获取单个

    var resp = client.Get<User>(3, d => d.Index(indexName));

    返回的类型为 GetResponse<User>,包含下面几个属性。

    index:表示索引,

    type:值固定为“_doc”,

    found:表示是否找到文档,

    version:文档的版本号,

    source:存储的数据user

    3.3.2 根据Id集合获取多个

     var resp = client.GetMany<User>(new List<long>() { 19L, 20L, 21L }, indexName);

    3.3.3 根据条件查询

    var resp = client.Search<User>(x => x.Index(indexName)
                                         .From(0)
                                         .Size(20)
                                         .Query(q => q.Range(r => r.Field(f => f.Age).GreaterThan(18)) &&
                                                     q.Range(r => r.Field(f => f.Age).LessThan(30)) &&
                                                     q.Term(t => t.Gender, true)));

    返回的类型为 ISearchResponse<User>,包含下面几个属性。

    TimedOut:查询是否超时

    Shards:完成这个搜索查询了多少个分片

    Took:此次查询消耗的时间

    MaxScore:此次查询中最符合查询条件的文档的最大得分

    Total:符合查询条件的总数

    Hits:存储的数据user集合

    例子只是简单的查询。ES专为查询而生,所以它的查询很灵活,后面单独讲。

     3.4 更新

    var user = new User()
    {
        Age = 18,
        Gender = false,
        Name = "test"
    };
    var resp4 = client.Update<User>(20, u => u.Index(indexName).Doc(user));

     返回的IsValid 表示是否更新成功。

     自己封装一个操作仓储,链接

     

       

  • 相关阅读:
    广商博客冲刺第六七天new
    广商博客沖刺第一天(new ver):
    20150529项目之典型用户与场景
    冲刺第二,三,四,五,六天
    冲刺第一天:
    Android 學習之旅!(2)
    20150512 作业6 团队项目之需求
    Android 學習之旅!(1)
    20150421 作业5 四则运算 测试与封装 5.1 5.2(doing)
    20150421 作业5 四则运算 测试与封装 5.1
  • 原文地址:https://www.cnblogs.com/MicroHeart/p/15481540.html
Copyright © 2020-2023  润新知