Elasticsearch nest實現類似Contains和Like功能

前言:近期在研究elasticsearch,開發語言c#,一個“簡單”的功能研究了一天,好費神(可能第一次使用es的原因)。這個功能就是:c#語言中StringContains功能。

 

例如:文本內容是:4G時代,網絡標準有FDD、TDD之分

1.搜索“FDD”,可以搜索出來;

2.搜索“FDDD”,不可以搜索出來。

這個功能看似簡單,像c#裏面ContainsSQL裏面Like都可以很容易的完成搜索要求,elasticsearch就稍微有點複雜了,因爲分詞的原因,導致第2種情況也可以搜索出來。網上看了很多文章,大多都千篇一律,可用價值不大,今天把我所得分享一下,希望有需求的同學少走些彎路。

 

要實現這個功能的思想是

 

1.創建索引的時候要設置字段的typekeyword(不分詞);

 

2.使用query_string查詢的時候,搜索內容前後加上*

開發環境

 

開發語言c#

 

Elasticsearch.Net版本:7.X

 

Nest版本:7.X

具體步驟和代碼實現如下:

 

第一步:定義實體(文檔內容)

 

public class StudentEntity

 

{

 

        public string eid { get; set; }

 

         [Text(Name = "title")]

 

        public string title { get; set; }

 

         [Keyword(Name = "content")]

 

        public string content { get; set; }

 

         public DateTime time { get; set; }

 

}

 

Content上面定義Keyword屬性,爲下面創建索引使用。

第二步:創建索引,索引名稱爲“news”

var nodes = new Uri[] { new Uri("http://localhost:9200") };

var pool = new StaticConnectionPool(nodes);

var settings = new ConnectionSettings(pool).DefaultIndex("news");

client = new ElasticClient(settings);

client.Indices.Create("news", c => c.Settings(s =>

s.NumberOfShards(5).NumberOfReplicas(1)).Map<StudentEntity>(m => m.AutoMap()));

創建好索引後,我們查看索引信息:

 

 

 

我們看到contenttype爲“keyword”,titletypetext

 

 

第三步:插入數據

 

 StudentEntity se = new StudentEntity()

 

{

 

      eid = "1000",

 

      title = "4G時代,網絡標準有FDD、TDD之分",

 

      content = "4G時代,網絡標準有FDD、TDD之分",

 

      time = Convert.ToDateTime("2020-06-19 19:28:32")

 

};

 

client.Index<StudentEntity>(se, s => s.Index("news"));

第四步:查詢

查詢語句1:輸入“*FDD*”,查詢字段content

結果搜索出來,符合條件:

 

 

查詢語句2:輸入“*FDDD*”,查詢字段content

結果搜索不出來,符合條件:

 

我們再來看看title搜索結果:

查詢語句:(1)輸入“*FDD*”,查詢字段title

結果搜索不出來,不符合條件:

 

 

 

(2)輸入“有FDD”,查詢字段title,結果搜索出來,符合條件。

(3)輸入“有FDDD”,查詢字段title,結果搜索出來,不符合條件。

 

C#代碼爲:

 

 var response = client.Search<StudentEntity>(s => s.From(0).Size(10).Index("news").Query(q => q.QueryString(r => r.DefaultField("content").Query("*有FDD*"))));

 

Console.WriteLine(JsonConvert.SerializeObject(response.Documents));

 

 特殊情況:

 

如果要搜索的內容中含有*,則在其前面加上\\即可,例如:*\\*有FDD*

 

 

 至此,類似Contains或者Like的功能就實現了,有需求的同學可以將上面思想或者代碼重新整合一下用到自己的項目中。

 

 在此要感謝QQ羣中幫助過我的同學:@無相,@臭小子,@快樂的小帥哥。

 

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