gpt4 book ai didi

.NetCore中使用NEST简单操作Elasticsearch

转载 作者:我是一只小鸟 更新时间:2023-02-17 22:31:21 26 4
gpt4 key购买 nike

C# 中访问 Elasticsearch 主要通过两个包 NEST 和 Elasticsearch.Net , NEST 用高级语法糖封装了 Elasticsearch.Net 可以通过类 Linq 的方式进行操作,而 Elasticsearch.Net 相比之下更为原始直接非常自由.

注意: ES 的 8.X 以上的版本有新的包 Elastic.Clients.Elasticsearc 支持.

此处使用 NEST ,我们通过 Nuget 安装,如下图:

1、准备结构 。

 准备以下实体 。

                          
                            public
                          
                          
                            class
                          
                          
                             Company
    {
        
                          
                          
                            public
                          
                          
                            string
                          
                           Id { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
        
                          
                          
                            public
                          
                          
                            string
                          
                           Name { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
        
                          
                          
                            public
                          
                          
                            string
                          
                           Description { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
        
                          
                          
                            public
                          
                           User User { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
    }
    
                          
                          
                            public
                          
                          
                            class
                          
                          
                             User
    {
        
                          
                          
                            public
                          
                          
                            string
                          
                           Name { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
        
                          
                          
                            public
                          
                          
                            int
                          
                           Gender { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
    }
                          
                        

2、连接ES 。

 如果是单机连接如下代码,可以直接在 Uri 上指定账号密码,也可以使用 ConnectionSettings 的 BasicAuthentication 来配置账号密码:

                          var singleNode = new Uri(
                          
                            "
                          
                          
                            http://elastic:123456@localhost:9200
                          
                          
                            "
                          
                          
                            );
    var connSettings 
                          
                          =
                          
                             new ConnectionSettings(singleNode);
                            
  //connSettings.BasicAuthentication("elastic", "123456"); var esClient
= new ElasticClient(connSettings);

如果是多个节点集群则如下代码:

                          var nodes =
                          
                             new Uri[]
    {
        new Uri(
                          
                          
                            "
                          
                          
                            http://esNode1:9200
                          
                          
                            "
                          
                          
                            ),
        new Uri(
                          
                          
                            "
                          
                          
                            http://esNode2:9200
                          
                          
                            "
                          
                          
                            ),
        new Uri(
                          
                          
                            "
                          
                          
                            http://esNode3:9200
                          
                          
                            "
                          
                          
                            )
    };
    var pool 
                          
                          =
                          
                             new StaticConnectionPool(nodes);
    var settings 
                          
                          =
                          
                             new ConnectionSettings(pool);
    var client 
                          
                          = new ElasticClient(settings);
                        

3、创建索引 。

索引名称必须符合规则否则创建会失败,比如索引只能小写,具体代码如下:

                          var indexName = 
                          
                            "
                          
                          
                            my_index1
                          
                          
                            "
                          
                          ;//
                          
                            索引名称
    var res 
                          
                          = await esClient.Indices.CreateAsync(indexName, o => o.Map(g => g.AutoMap<Company>()));//映射结构
                        

 也可以在向索引插入数据的时候自动判断是否存在索引,不存在会自动创建。 索引结构字段映射一但创建就无法修改,可以通过新建索引然后转移数据的方式修改索引结构,但是可以往里面新增字段映射,比如修改了实体结构新的字段将会被映射.

4、插入数据 。

使用 IndexDocumentAsync 方法插入单条数据需要在 ConnectionSettings 的 DefaultIndex 方法设置默认索引。使用 IndexAsync 插入单条数据时需要选择指定索引,如下:

                          
                            var
                          
                           singleNode = 
                          
                            new
                          
                           Uri(
                          
                            "
                          
                          
                            http://localhost:9200
                          
                          
                            "
                          
                          
                            );
    
                          
                          
                            var
                          
                           connSettings = 
                          
                            new
                          
                          
                             ConnectionSettings(singleNode);
    connSettings.BasicAuthentication(
                          
                          
                            "
                          
                          
                            elastic
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            123456
                          
                          
                            "
                          
                          
                            );
    
                          
                          
                            var
                          
                           esClient = 
                          
                            new
                          
                           ElasticClient(connSettings.DefaultIndex(
                          
                            "
                          
                          
                            my_index1
                          
                          
                            "
                          
                          
                            ));
    
                          
                          
                            var
                          
                           indexName = 
                          
                            "
                          
                          
                            my_index1
                          
                          
                            "
                          
                          
                            ;
    
                          
                          
                            var
                          
                           company = 
                          
                            new
                          
                          
                             Company()
    {
        Name 
                          
                          = 
                          
                            "
                          
                          
                            超级公司bulk
                          
                          
                            "
                          
                          
                            ,
        Description 
                          
                          = 
                          
                            "
                          
                          
                            超级描述bulk
                          
                          
                            "
                          
                          
                            ,
    };
    
                          
                          
                            var
                          
                           res1 = 
                          
                            await
                          
                          
                             esClient.IndexDocumentAsync(company);
    
                          
                          
                            var
                          
                           res2 = 
                          
                            await
                          
                           esClient.IndexAsync(company, g => g.Index(indexName))    
                        

 如果需要批量插入需要用 BulkDescriptor 对象包裹,然后使用 BulkAsync 方法插入,或者不要包裹直接用 IndexManyAsync 方法插入,具体如下:

                          
                            var
                          
                           company = 
                          
                            new
                          
                          
                             Company()
    {
                          
                          
                            
        Name 
                          
                          = 
                          
                            "
                          
                          
                            超级公司bulk
                          
                          
                            "
                          
                          
                            ,
        Description 
                          
                          = 
                          
                            "
                          
                          
                            超级描述bulk
                          
                          
                            "
                          
                          
                            
    });
    BulkDescriptor descriptor 
                          
                          = 
                          
                            new
                          
                          
                             BulkDescriptor();
    descriptor.Index
                          
                          <Company>(op =>
                          
                             op.Document(company).Index(indexName));
    
                          
                          
                            var
                          
                           res = 
                          
                            await
                          
                          
                             esClient.BulkAsync(descriptor);
    
                          
                          
                            //
                          
                          
                            var list = new List<Company>();
    
                          
                          
                            //
                          
                          
                            list.Add(company);
    
                          
                          
                            //
                          
                          
                            var res = await esClient.IndexManyAsync(list, indexName);  
                          
                        

 如果实体有 Id 则会使用 Id 的值做为 _id 的索引文档唯一值,或者可以通过手动指定如 await esClient.IndexAsync(company, g => g.Index(indexName).Id(company.Id)) ,如果id相同执行插入操作则为更新不会重复插入。在新增后是会返回id等信息可以加以利用.

5、删除数据 。

删除指定单条数据需要知道数据的 id ,如下两种方式:

                          DocumentPath<Company> deletePath = 
                          
                            new
                          
                           DocumentPath<Company>
                          
                            (Guid.Empty);
    
                          
                          
                            var
                          
                           delRes = 
                          
                            await
                          
                           esClient.DeleteAsync(deletePath, g =>
                          
                             g.Index(indexName));
    
                          
                          
                            //
                          
                          
                            或者
                          
                          
    IDeleteRequest request = 
                          
                            new
                          
                           DeleteRequest(indexName, 
                          
                            "
                          
                          
                            1231
                          
                          
                            "
                          
                          
                            );
    
                          
                          
                            var
                          
                           delRes = 
                          
                            await
                          
                           esClient.DeleteAsync(request);
                        

 多条删除使用 DeleteByQueryAsync 方法进行匹配删除,下面两种方式等价,删除 Description 字段模糊查询有 描述 的数据(最多10条):

                          
                            var
                          
                           req = 
                          
                            new
                          
                           DeleteByQueryRequest<Company>
                          
                            (indexName)
    {
        MaximumDocuments 
                          
                          = 
                          
                            10
                          
                          ,
                          
                            //
                          
                          
                            一次最多删几条
                          
                          
        Query = 
                          
                            new
                          
                          
                             MatchQuery()
                {
                    Field 
                          
                          = 
                          
                            "
                          
                          
                            description
                          
                          
                            "
                          
                          
                            ,
                    Query 
                          
                          = 
                          
                            "
                          
                          
                            描述
                          
                          
                            "
                          
                          
                            
                }
    };
    
                          
                          
                            var
                          
                           result = 
                          
                            await
                          
                          
                             esClient.DeleteByQueryAsync(req);
    
                          
                          
                            //
                          
                          
                            等价于
                          
                          
                            var
                          
                           result = 
                          
                            await
                          
                           esClient.DeleteByQueryAsync<Company>(dq =>
                          
                            
                    dq.MaximumDocuments(
                          
                          
                            10
                          
                          
                            ).Query(
                            q 
                          
                          => q.Match(tr => tr.Field(fd => fd.Description).Query(
                          
                            "
                          
                          
                            描述
                          
                          
                            "
                          
                          
                            ))).Index(indexName)
                     );
                          
                        

 6、更新数据 。

 除了上述插入数据时自动根据 id 进行更新外还有以下的主动更新.

 根据 id 更新单条数据以下代码等价,可以更新部分字段值,但是 _id 是确定就不会更改的虽然对应的 Id 字段已被修改:

                          DocumentPath<Company> deletePath = 
                          
                            new
                          
                           DocumentPath<Company>(
                          
                            "
                          
                          
                            1231
                          
                          
                            "
                          
                          
                            );
    
                          
                          
                            var
                          
                           res = 
                          
                            await
                          
                           esClient.UpdateAsync(deletePath ,(p) =>
                          
                             p.Doc(company).Index(indexName));
    
                          
                          
                            //
                          
                          
                            等价于
                          
                          
    IUpdateRequest<Company, Company> request = 
                          
                            new
                          
                           UpdateRequest<Company, Company>(indexName, 
                          
                            "
                          
                          
                            1231
                          
                          
                            "
                          
                          
                            )
    {
        Doc 
                          
                          = 
                          
                            new
                          
                          
                             Company()
        {
            Id 
                          
                          = 
                          
                            "
                          
                          
                            888
                          
                          
                            "
                          
                          
                            ,
            Description 
                          
                          = 
                          
                            "
                          
                          
                            11111
                          
                          
                            "
                          
                          
                            ,
        }
    };
    
                          
                          
                            var
                          
                           res = 
                          
                            await
                          
                           esClient.UpdateAsync(request);
                        

 如果有多个 id 更新多条数据可以用如下方法:

                          
                            var
                          
                           res = esClient.Bulk(b => b.UpdateMany(
                          
                            new
                          
                           List<Company>() { 
                          
                            new
                          
                          
                             Company()
    {
        Id
                          
                          =
                          
                            "
                          
                          
                            1231
                          
                          
                            "
                          
                          
                            ,
    } }, (b, u) 
                          
                          => b.Id(u.Id).Index(indexName).Doc(
                          
                            new
                          
                           Company { Name = 
                          
                            "
                          
                          
                            我无语了
                          
                          
                            "
                          
                           })));
                        

通过条件批量更新如下, 。

                          
                            var
                          
                           req = 
                          
                            new
                          
                           UpdateByQueryRequest<Company>
                          
                            (indexName)
    {
        MaximumDocuments 
                          
                          = 
                          
                            10
                          
                          ,
                          
                            //
                          
                          
                            一次最多更新几条
                          
                          
        Query = 
                          
                            new
                          
                          
                             MatchQuery()
        {
            Field 
                          
                          = 
                          
                            "
                          
                          
                            description
                          
                          
                            "
                          
                          
                            ,
            Query 
                          
                          = 
                          
                            "
                          
                          
                            66
                          
                          
                            "
                          
                          
                            ,
        },
        Script 
                          
                          = 
                          
                            new
                          
                          
                             ScriptDescriptor()
        .Source($
                          
                          
                            "
                          
                          
                            ctx._source.description = params.description;
                          
                          
                            "
                          
                          
                            )
        .Params(
                          
                          
                            new
                          
                           Dictionary<
                          
                            string
                          
                          , 
                          
                            object
                          
                          >
                          
                            
        {
            { 
                          
                          
                            "
                          
                          
                            description
                          
                          
                            "
                          
                          ,
                          
                            "
                          
                          
                            小时了123123123
                          
                          
                            "
                          
                          
                            }
        }),
        Refresh 
                          
                          = 
                          
                            true
                          
                          
                            
    };
    
                          
                          
                            var
                          
                           result = 
                          
                            await
                          
                           esClient.UpdateByQueryAsync(req);
                        

 7、数据查询 。

上文中的更新等都用到了查询过滤,此处就用网上的这个例子吧:

                          
                            var
                          
                           result = client.Search<VendorPriceInfo>
                          
                            (
                s 
                          
                          =>
                          
                             s
                    .Explain() 
                          
                          
                            //
                          
                          
                            参数可以提供查询的更多详情。
                          
                          
                    .FielddataFields(fs => fs 
                          
                            //
                          
                          
                            对指定字段进行分析
                          
                          
                        .Field(p =>
                          
                             p.vendorFullName)
                        .Field(p 
                          
                          =>
                          
                             p.cbName)
                    )
                    .From(
                          
                          
                            0
                          
                          ) 
                          
                            //
                          
                          
                            跳过的数据个数
                          
                          
                    .Size(
                          
                            50
                          
                          ) 
                          
                            //
                          
                          
                            返回数据个数
                          
                          
                    .Query(q =>
                          
                            
                        q.Term(p 
                          
                          => p.vendorID, 
                          
                            100
                          
                          ) 
                          
                            //
                          
                          
                             主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):
                          
                          
                        &&
                          
                            
                        q.Term(p 
                          
                          => p.vendorName.Suffix(
                          
                            "
                          
                          
                            temp
                          
                          
                            "
                          
                          ), 
                          
                            "
                          
                          
                            姓名
                          
                          
                            "
                          
                          ) 
                          
                            //
                          
                          
                            用于自定义属性的查询 (定义方法查看MappingDemo)
                          
                          
                        &&
                          
                            
                        q.Bool( 
                          
                          
                            //
                          
                          
                            bool 查询
                          
                          
                            b =>
                          
                             b
                                .Must(mt 
                          
                          => mt 
                          
                            //
                          
                          
                            所有分句必须全部匹配,与 AND 相同
                          
                          
                                    .TermRange(p => p.Field(f => f.priceID).GreaterThan(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          ).LessThan(
                          
                            "
                          
                          
                            1
                          
                          
                            "
                          
                          ))) 
                          
                            //
                          
                          
                            指定范围查找
                          
                          
                                .Should(sd => sd 
                          
                            //
                          
                          
                            至少有一个分句匹配,与 OR 相同
                          
                          
                                    .Term(p => p.priceID, 
                          
                            32915
                          
                          
                            ),
                                    sd 
                          
                          => sd.Terms(t => t.Field(fd => fd.priceID).Terms(
                          
                            new
                          
                          [] {
                          
                            10
                          
                          , 
                          
                            20
                          
                          , 
                          
                            30
                          
                          })),
                          
                            //
                          
                          
                            多值
                                    
                          
                          
                            //
                          
                          
                            ||
                                    
                          
                          
                            //
                          
                          
                            sd.Term(p => p.priceID, 1001)
                                    
                          
                          
                            //
                          
                          
                            ||
                                    
                          
                          
                            //
                          
                          
                            sd.Term(p => p.priceID, 1005)
                          
                          
                                    sd => sd.TermRange(tr => tr.GreaterThan(
                          
                            "
                          
                          
                            10
                          
                          
                            "
                          
                          ).LessThan(
                          
                            "
                          
                          
                            12
                          
                          
                            "
                          
                          ).Field(f =>
                          
                             f.vendorPrice))
                                )
                                .MustNot(mn 
                          
                          => mn
                          
                            //
                          
                          
                            所有分句都必须不匹配,与 NOT 相同
                          
                          
                                    .Term(p => p.priceID, 
                          
                            1001
                          
                          
                            )
                                    ,
                                    mn 
                          
                          =>
                          
                             mn.Bool(
                                        bb
                          
                          =>bb.Must(mt=>
                          
                            mt
                                            .Match(mc
                          
                          =>mc.Field(fd=>fd.carName).Query(
                          
                            "
                          
                          
                            至尊
                          
                          
                            "
                          
                          
                            ))
                                        ))
                                )
                            )
                    )
                          
                          
                            //
                          
                          
                            查询条件
                          
                          
                .Sort(st => st.Ascending(asc => asc.vendorPrice))
                          
                            //
                          
                          
                            排序
                          
                          
                .Source(sc => sc.Include(ic =>
                          
                             ic
                    .Fields(
                        fd 
                          
                          =>
                          
                             fd.vendorName,
                        fd 
                          
                          =>
                          
                             fd.vendorID,
                        fd 
                          
                          =>
                          
                             fd.priceID,
                        fd 
                          
                          => fd.vendorPrice))) 
                          
                            //
                          
                          
                            返回特定的字段
                          
                          
                                           );
    
                          
                        

  。

最后此篇关于.NetCore中使用NEST简单操作Elasticsearch的文章就讲到这里了,如果你想了解更多关于.NetCore中使用NEST简单操作Elasticsearch的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com