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 =&gt; fs
            .Field(p =&gt; p.Content)
)

)

方法2

.Highlight(h => h
.Fields(
fs => fs
.Field(p => p.Title)
.PreTags("<em>")
.PostTags("</em>"),

    fs =&gt; fs
            .Field(p =&gt; p.Content)
            .PreTags("&lt;em&gt;")
            .PostTags("&lt;/em&gt;")
)

)

高亮查詢

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&lt;Article&gt;(s =&gt; s
    .From(0)
    .Size(10)
    .Query(q =&gt; q
        .Match(m =&gt; m
            .Field(f =&gt; f.Title)
            .Query(keywords))
        )
    .Highlight(h =&gt; h.Fields(e =&gt; e.Field("title")
                    .PreTags("&lt;b style='color:red'&gt;")
                    .PostTags("&lt;/b&gt;")))
    //.Sort(r =&gt; r.Descending(q =&gt; q.CreateDate))
    
    //在工作中把&lt;b style='color:red'&gt;這個換成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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章