ElasticSearch7.x系列二:Kibana的使用和C#的Nest客户端

摘要:
目录前言Kibana查询ElasticSearch使用C#的Nest查询Elastic Search连接使用连接池批量添加文档添加文档搜索文档查询指定字段全文搜索全文搜索突出显示的查询聚合查询结构化查询:特征,查询结果为真或假非结构化搜索:特征,在全文字段中搜索组合查询布尔查询编写错误推荐布尔查询选择要返回的字段Forewords ElasticSearch、Kibana、Logstas

目录
前言

ElasticSearch,Kibana,Logstash等安装上一章讲完了,这一章讲讲ELasticSearch怎么使用

两种方式,一种是直接写ElasticSearch查询语句,当然是在Kibana里面

还有一种是用代码写,可以用Java,C#,PHP,Python等,我这里使用C#

Kibana查询ElasticSearch
#创建
PUT /test/user/1
{
	"name":"许嵩",
	"age":34,
	"tags":["a","b","c"]
}

#查询index里面的数量
GET test/_count


#查询id为1的
GET test/user/1 


#查询name包含许嵩的
GET article/_search?q=title:许嵩


# 也可以使用这种
GET article/_search
{
  "query": {
    "match": {
      "title": "许嵩"
    }
  }
}

# 高亮查询,讲一下,所谓的高亮就是给关键字加上自己定义的一个标签,一般都是em,然后你在css里面定义em为高亮黄色或者红色即可

GET article/_search
{
  "query": {
    "match": {
      "title": "许嵩"
    }
  },
  "highlight": {
    "pre_tags": [
      "<em>"
    ],
    "post_tags": [
      "</em>"
    ],
    "encoder": "html",
    "fields": {
      "title": {
        "force_source": true,
        "fragment_size": 150,
        "fragmenter": "span",
        "number_of_fragments": 3,
        "no_match_size": 150
      }
    }
  }
}

# 更新
POST /test/user/1/_update
{
	"doc":{
		"name":"vae"
	}
}
使用C#的Nest查询ElasticSearch

在NuGet里面下Nest

连接

var settings = new ConnectionSettings(new Uri("http://192.168.3.8:9200/")).DefaultIndex("article");
var client = new ElasticClient(settings);

使用连接池

可以多搞几个ElasticSearch服务器

var uris = new[]
{
    new Uri("http://localhost:9200"),
    new Uri("http://localhost:9201"),
    new Uri("http://localhost:9202"),
};

var connectionPool = new SniffingConnectionPool(uris);
var settings = new ConnectionSettings(connectionPool)
    .DefaultIndex("people");

var client = new ElasticClient(settings);

增加文档

var person = new Person
{
    Id = 1,
    FirstName = "Martijn",
    LastName = "Laarman"
};

//同步
var indexResponse = client.IndexDocument(person); 

//异步
var asyncIndexResponse = await client.IndexDocumentAsync(person); 

批量增加文档

var bulkAllObservable = client.BulkAll(list, b => b
    .Index("article")
    .BackOffTime("30s")
    .BackOffRetries(2)
    .RefreshOnCompleted()
    .MaxDegreeOfParallelism(Environment.ProcessorCount)
    .Size(1000)
)
.Wait(TimeSpan.FromMinutes(15), next =>
{
    // do something e.g. write number of pages to console
});

搜索文档

  1. From(0) 从0开始
  2. Size(10) 每次找10个
  3. Query 查询
  4. Match 模糊匹配
  5. Field 字段

查询指定字段

比如我只查标题

var search = client.Search<AllInformationViewModel>(s => s
     .Index(indexName)
     .From(page)
     .Size(10)
     .Query(q => q
        .Match(m => m
            .Field(f => f.Title)
            .Query(keyword))

全文检索

全文检索的意思就是全部字段我都查找,标题啊,描述啊,摘要啊

var searchAll = client.Search<AllInformationViewModel>(s => s
    .Index(indexName)
    .From(page)
    .Size(10)
    .Query(q => q
        .QueryString(qs => qs
            .Query(keyword).DefaultOperator(Operator.And))

全文检索高亮

我全文检索查的标题,描述都得给我高亮

#方法1
.Highlight(h => h
    .PreTags("<em>")
    .PostTags("</em>")
    .Encoder(HighlighterEncoder.Html)
    .Fields(
        fs => fs
            .Field(p => p.Title),
            
        fs => fs
                .Field(p => p.Content)
    )
)
    
#方法2    
.Highlight(h => h 
    .Fields(
        fs => fs
            .Field(p => p.Title)
                .PreTags("<em>")
                .PostTags("</em>"),
            

        fs => fs
                .Field(p => p.Content)
                .PreTags("<em>")
                .PostTags("</em>")
    )
)

高亮查询

public ActionResult Index(string keywords="")
{
    var settings = new ConnectionSettings(new Uri("http://192.168.3.8:9200/")).DefaultIndex("article");
    var client = new ElasticClient(settings);

    var search = client.Search<Article>(s => s
        .From(0)
        .Size(10)
        .Query(q => q
            .Match(m => m
                .Field(f => f.Title)
                .Query(keywords))
            )
        .Highlight(h => h.Fields(e => e.Field("title")
                        .PreTags("<b style='color:red'>")
                        .PostTags("</b>")))
        //.Sort(r => r.Descending(q => q.CreateDate))
        
        //在工作中把<b style='color:red'>这个换成em标签就可以了,然后在css里面给em加上高亮即可
    );

    foreach (var hit in search.Hits)
    {
        foreach (var highlightField in hit.Highlight)
        {
            if (highlightField.Key == "title")
            {
                foreach (var highlight in highlightField.Value)
                {
                    hit.Source.Title = highlight.ToString();
                }
            }
        }
    }

    return View(search.Documents);
}

聚合查询

var searchResponse = await client.SearchAsync<Person>(s => s
    .Size(0)
    .Query(q => q
         .Match(m => m
            .Field(f => f.FirstName)
            .Query("许嵩")
         )
    )
    .Aggregations(a => a
        .Terms("last_names", ta => ta
            .Field(f => f.LastName)
        )
    )
);

var termsAggregation = searchResponse.Aggregations.Terms("last_names");

结构化: 特点,查询结果要么是true要么是false

结构化一般查找时间,数字或者标题之类的,查询的答案始终是或否;文档是查询的匹配项,或者不是。

开始时间在2017年之间的所有数据

var searchResponse = _client.Search<Project>(s => s
    .Query(q => q
        .DateRange(r => r
            .Field(f => f.StartTime)
            .GreaterThanOrEquals(new DateTime(2017, 01, 01))
            .LessThan(new DateTime(2018, 01, 01))
        )
    )
);
{
  "query": {
    "range": {
      "startedOn": {
        "lt": "2018-01-01T00:00:00",
        "gte": "2017-01-01T00:00:00"
      }
    }
  }
}

非结构化搜索: 特点,在全文字段中搜索

我们常用的搜索就是非结构化搜索,例如我搜一个人名

var searchResponse = _client.Search<Project>(s => s
    .Query(q => q
        .Match(m => m
            .Field(f => f.Name)
            .Query("许嵩")
        )
    )
);

组合查询

查找姓是 许 名是嵩的,并且时间必须在2017年

var searchResponse = _client.Search<Project>(s => s
    .Query(q => q
        .Bool(b => b
            .Must(mu => mu
                .Match(m => m 
                    .Field(f => f.FirstName)
                    .Query("许")
                ), mu => mu
                .Match(m => m 
                    .Field(f => f.LastName)
                    .Query("嵩")
                )
            )
            .Filter(fi => fi
                 .DateRange(r => r
                    .Field(f => f.StartedOn)
                    .GreaterThanOrEquals(new DateTime(2017, 01, 01))
                    .LessThan(new DateTime(2018, 01, 01)) 
                )
            )
        )
    )
);
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "leadDeveloper.firstName": {
              "query": "Russ"
            }
          }
        },
        {
          "match": {
            "leadDeveloper.lastName": {
              "query": "Cam"
            }
          }
        }
      ],
      "filter": [
        {
          "range": {
            "startedOn": {
              "lt": "2018-01-01T00:00:00",
              "gte": "2017-01-01T00:00:00"
            }
          }
        }
      ]
    }
  }
}

还有一个更好用的写法

searchResponse = _client.Search<Project>(s => s
    .Query(q => q
        .Match(m => m
            .Field(f => f.FirstName)
            .Query("许")
        ) && q 
        .Match(m => m
            .Field(f => f.LastName)
            .Query("嵩")
        ) && +q 
        .DateRange(r => r
            .Field(f => f.StartedOn)
            .GreaterThanOrEquals(new DateTime(2017, 01, 01))
            .LessThan(new DateTime(2018, 01, 01))
        )
    )
);

组合记得使用 +

布尔查询

不好的写法

var searchResults = this.Client.Search<Project>(s => s
    .Query(q => q
        .Bool(b => b
            .Should(
                bs => bs.Term(p => p.Name, "x"),
                bs => bs.Term(p => p.Name, "y")
            )
        )
    )
);

这种写法很不好,如果很多bool嵌套查询,多个bool查询,结果是啥?结果就会像下图一样

你的代码会变成凹陷缩进的样子,很丑,而且不利于维护,看着就头大了

ElasticSearch7.x系列二:Kibana的使用和C#的Nest客户端第1张

推荐使用的bool查询

var firstSearchResponse = client.Search<Project>(s => s
    .Query(q => q
        .Term(p => p.Name, "x") || q
        .Term(p => p.Name, "y")
    )
);
var firstSearchResponse = client.Search<Project>(s => s
    .Query(q => q
        .Term(p => p.Name, "x") && q
        .Term(p => p.Name, "y")
    )
);
var firstSearchResponse = client.Search<Project>(s => s
    .Query(q => !q
        .Term(p => p.Name, "x")
    )
);

选择要返回的字段

我们查询不需要所有的字段,只需要几个字段就可以

查询全部的数据,但是只要Name和StartTime这两个字段

var searchResponse = _client.Search<Project>(s => s
    .StoredFields(sf => sf
        .Fields(
            f => f.Name,
            f => f.StartTime
        )
    )
    .Query(q => q
        .MatchAll()
    )
);

源筛选

var searchResponse = _client.Search<Project>(s => s
    .Source(sf => sf
        .Includes(i => i    //包括以下字段
            .Fields(
                f => f.Name,
                f => f.StartedOn
            )
        )
        .Excludes(e => e 
            .Fields("num*")   //排除其他字段
        )
    )
    .Query(q => q
        .MatchAll()
    )
);

免责声明:文章转载自《ElasticSearch7.x系列二:Kibana的使用和C#的Nest客户端》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇eslint在webstorm的使用express 配置 https 服务 ( 以阿里云服务器为例), 探索一周终于搞定下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

谷粒商城安装ES及入门(十六)

102、全文检索-ElasticSearch-简介 --109、全文检索-ElasticSearch-入门-删除数据&bulk批量操作导入样本测试数据  安装 [root@play ~]# docker pull elasticsearch:7.4.2 7.4.2: Pulling from library/elasticsearch d8d02d...

Elasticsearch 删除数据

原文链接:http://www.zhoubotong.site/post/8.html版本:elasticsearch7.0 删除数据分为两种:1: 删除索引(数据和表结构同时删除,作用同SQLSERVER 中DROP TABLE "表格名"), 2: 删除数据(不删除表结构,作用同SQLSERVER中Delete 语句) 这里简单介绍下单个删除和批量删除...

在Linux上运行C#

众所周知,C#是Microsoft推出的.NET语言,只能在.NET平台上运行,例如Win 9x、ME、NT、2000、XP和Win CE之类的操作系统。但是,现在却有了一个叫做Mono的项目,它的目标就是把.NET及其编程语言移植到非Windows的平台上。现在,C#是唯一被移植到非Windows平台的.NET语言。   在任何一个平台(操作系统+硬件体...

prometheus监控elasticsearch

prometheus监控es,同样采用exporter的方案。 项目地址: elasticsearch_exporter:https://github.com/justwatchcom/elasticsearch_exporter 1、安装部署 现有es三节点的集群,环境大概如下: 主机 组件 192.168.75.11 prometheus...

C#.Net C/S快速开发框架V2.2版本介绍

C#.Net C/S快速开发框架V2.2版本介绍 C/S结构快速开发框架V2.2 解决方案:CSFramework.* 命名的模块为框架共公模块(核心模块)框架版本:V2.2CSFramework3.* 是客户端及服务端的业务模块.高级版(WebService架构)已升级到3.0,此解决方案模块名是以高级版命名的。注:标准版和高级版框架核心是一样的,...

ELK日志分析系统(4)-elasticsearch数据存储

1. 概述 logstash把格式化的数据发送到elasticsearch以后,elasticsearch负责存储搜索日志数据 elasticsearch的搜索接口还是很强大的,这边不详细展开,因为kibana会去调用el的接口; 本文将讲解elasticsearch的相关配置和遇到的问题,至于elasticsearch的相关搜索使用,后面会找个时间整理一...