ElasticSearch& Kibana的使用&C#的Nest客户端
前言
两种方式,一种是直接写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
});
搜索文档
From(0) 从0开始 Size(10) 每次找10个 Query 查询 Match 模糊匹配 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查询,结果是啥?结果就会像下图一样
你的代码会变成凹陷缩进的样子,很丑,而且不利于维护,看着就头大了
推荐使用的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()
)
);
来源:https://blog.csdn.net/weixin_41601114/article/details/108789067
https://www.iwmyx.cn/elasticsearchkibananest.html