自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在我們的Asp.NET Core應(yīng)用程序中使用ElasticSearch高級(jí)功能

開發(fā) 后端
在本文中,我向您展示了如何使用Elasticsearch對(duì)復(fù)雜的實(shí)際場(chǎng)景進(jìn)行有效的處理,分析和搜索數(shù)據(jù)。希望我對(duì)這個(gè)話題感興趣。

[[432709]]

在上一篇文章中[1],我們討論了將ElasticSearch用作簡單的全文本搜索引擎,如何快速安裝和配置它以及如何將其集成到我們的.NET Web應(yīng)用程序中。

今天,我們?nèi)匀灰陔娮由虅?wù)網(wǎng)站中向您展示如何使用ElasticSearch的許多功能來改善搜索。

我們使用了沒有嵌套類的平面Product類來輕松管理搜索,但是這種方法有很多限制。然后,我們引入了一個(gè)新的數(shù)據(jù)模型,以便任何對(duì)象都是要建模的實(shí)體。一個(gè)文檔可以包含無限數(shù)量的相關(guān)字段和值(數(shù)組,簡單和復(fù)雜類型),并保存為JSON文檔。

我們的模型產(chǎn)品類別已變?yōu)椋?/p>

  1. public class Product 
  2.     public int Id { get; set; } 
  3.     public string Ean { get; set; } 
  4.     public string Name { get; set; } 
  5.     public string Description { get; set; } 
  6.     public Brand Brand { get; set; } 
  7.     public Category Category { get; set; } 
  8.     public Store Store { get; set; } 
  9.     public decimal Price { get; set; } 
  10.     public string Currency { get; set; } 
  11.     public int Quantity { get; set; } 
  12.     public float Rating { get; set; } 
  13.     public DateTime ReleaseDate { get; set; } 
  14.     public string Image { get; set; } 
  15.     public List<Review> Reviews { get; set; } 

其中品牌,類別,商店評(píng)論和用戶類別分別是:

  1. public class Brand 
  2.     public int Id { get; set; } 
  3.     public string Name { get; set; } 
  4.     public string Description { get; set; } 
  5.  
  6. public class Category 
  7.     public int Id { get; set; } 
  8.     public string Name { get; set; } 
  9.     public string Description { get; set; } 
  10.  
  11. public class Store 
  12.     public int Id { get; set; } 
  13.     public string Name { get; set; } 
  14.     public string Description { get; set; } 
  15.  
  16. public class Review 
  17.     public int Id { get; set; } 
  18.     public short Rating { get; set; } 
  19.     public string Description { get; set; } 
  20.     public User User { get; set; } 
  21.  
  22. public class User 
  23.     public int Id { get; set; } 
  24.     public string FirstName { get; set; } 
  25.     public string LastName { get; set; } 
  26.     public string IPAddress { get; set; } 
  27.     public GeoIp GeoIp { get; set; } 

GeoIp是NEST庫中用于地理數(shù)據(jù)的類。產(chǎn)品索引已被簡單地命名為產(chǎn)品。我們以這種方式創(chuàng)建和配置了它:

  1. client.Indices.Create(“products”, index => index 
  2.     .Map<Product>(x => x.AutoMap()) 
  3.     .Map<Brand>(x => x.AutoMap()) 
  4.     .Map<Category>(x => x.AutoMap()) 
  5.     .Map<Store>(x => x.AutoMap()) 
  6.     .Map<Review>(x => x.AutoMap()) 
  7.     .Map<User>(x => x.AutoMap() 
  8.         .Properties(props => props 
  9.             .Keyword(t => t.Name("fullname")) 
  10.             .Ip(t => t.Name(dv => dv.IPAddress)) 
  11.             .Object<GeoIp>(t => t.Name(dv => dv.GeoIp)) 
  12.         ) 
  13.     ) 

我們專門為ElasticSearch索引創(chuàng)建一個(gè)名為fullname的新屬性,用于名為fullname的User類,并定義了將要處理的地理信息。 為了使我們的產(chǎn)品能夠在索引之前進(jìn)行處理,一種有用的方法是node.ingest,即進(jìn)行文檔預(yù)處理的節(jié)點(diǎn)。接收節(jié)點(diǎn)攔截所有索引請(qǐng)求,甚至是批量索引請(qǐng)求,并將所有定義的轉(zhuǎn)換應(yīng)用于其內(nèi)容,然后將文檔發(fā)還給索引API。

必須通過以下參數(shù)在配置文件elasticsearch.yml中。

啟用node.ingest:

  1. node.ingest: true 

在我們的示例中,我們使用相同的節(jié)點(diǎn)進(jìn)行搜索和攝取,我們不需要編寫代碼來管理攝取節(jié)點(diǎn),但是,如果我們要擁有一組專用的攝取節(jié)點(diǎn),則必須配置ElasticSearch客戶如下:

  1. var pool = new StaticConnectionPool(new []  
  2.     new Uri("http://ingestnode1:9200"), 
  3.     new Uri("http://ingestnode2:9200"), 
  4.     new Uri("http://ingestnode3:9200"
  5. }); 
  6. var settings = new ConnectionSettings(pool); 
  7. var client = new ElasticClient(settings); 

為了對(duì)文檔進(jìn)行預(yù)處理,需要在建立索引之前定義一個(gè)管道,該管道指定一組能夠轉(zhuǎn)換該文檔的過程。有許多默認(rèn)過程可供使用。例如:GeoIP從IP地址獲取地理信息,JSON將字符串轉(zhuǎn)換為JSON對(duì)象,小寫和大寫,Drop刪除與某些參數(shù)匹配的文檔。您也可以創(chuàng)建自定義過程。我們?cè)陧?xiàng)目中使用的管道是:

  1. client.Ingest.PutPipeline("product-pipeline", p => p 
  2.                 .Processors(ps => ps 
  3.                     .Uppercase<Brand>(s => s 
  4.                         .Field(t => t.Name
  5.                     ) 
  6.                     .Uppercase<Category>(s => s 
  7.                         .Field(t => t.Name
  8.                     ) 
  9.                     .Set<User>(s => s.Field("fullname"
  10.                         .Value(s.Field(f => f.FirstName) + " " +  
  11.                              s.Field(f => f.LastName))) 
  12.                     .GeoIp<User>(s => s 
  13.                         .Field(i => i.IPAddress) 
  14.                         .TargetField(i => i.GeoIp) 
  15.                     ) 
  16.                 ) 
  17.             ); 

該管道處理文檔,以便:

  • Brand.Name和Category.Name將通過大寫輸入以大寫形式索引;
  • User.fullname將包含名字和姓氏(設(shè)置攝取);
  • User.IPAddress將成為地理定位的地理地址(GeoIp提取)。

管道以ElasticSearch集群狀態(tài)保存,要使用它們,您必須在索引請(qǐng)求中指定管道參數(shù),以便攝取節(jié)點(diǎn)知道必須使用哪個(gè)管道:

  1. client.Bulk(b => b 
  2.     .Index("products"
  3.     .Pipeline("product-pipeline"
  4.     .Timeout("5m")  
  5.     .Index<Person>(/*snip*/) 
  6.     .Index<Person>(/*snip*/) 
  7.     .Index<Person>(/*snip*/) 
  8.     .RequestConfiguration(rc => rc 
  9.         .RequestTimeout(TimeSpan.FromMinutes(5))  
  10.     ) 
  11. ); 

通過這種方式,我們定義了索引編制過程,以便我們可以根據(jù)需要獲取文檔清單。在使用創(chuàng)建的管道為文檔建立索引之后,我們可以通過使用瀏覽器http:// localhost:9200 / products / _search進(jìn)行訪問來檢查它們。我們得到類似于以下結(jié)果:

如上一篇文章所述,搜索過程基于文檔分析。這是第一個(gè)階段的令牌化過程(將文本分成小塊,稱為令牌),另一個(gè)是規(guī)范化過程(它允許您查找與不等于搜索詞但足夠相似以至于相關(guān)的令牌的匹配項(xiàng))為搜索建立索引的文本。分析儀執(zhí)行此過程。

分析儀由三個(gè)主要部分組成:

1.0個(gè)或多個(gè)字符過濾器

2.1個(gè)分詞器

3.0個(gè)或多個(gè)令牌過濾器

有一些默認(rèn)的分析器可以使用,但是,為了根據(jù)我們的要求提高搜索的準(zhǔn)確性,我們創(chuàng)建了一個(gè)自定義分析器。

定制分析器使我們能夠在分析過程中控制令牌化之前對(duì)文檔的任何更改,如何將其轉(zhuǎn)換為令牌以及如何對(duì)其進(jìn)行規(guī)范化。

這是我們的自定義分析器:

  1. var an = new CustomAnalyzer(); 
  2. an.CharFilter = new List<string>(); 
  3. an.CharFilter.Add("html_strip"); 
  4. an.Tokenizer = "edgeNGram"
  5. an.Filter = new List<string>(); 
  6. an.Filter.Add("standard"); 
  7. an.Filter.Add("lowercase"); 
  8. an.Filter.Add("stop"); 
  9.  
  10. settings.Analysis.Tokenizers.Add("edgeNGram", new Nest.EdgeNGramTokenizer 
  11.     MaxGram = 15, 
  12.     MinGram = 3 
  13. }); 
  14.  
  15. settings.Analysis.Analyzers.Add("product-analyzer", an); 

我們的分析器使用標(biāo)準(zhǔn)的標(biāo)記化方法,創(chuàng)建3至15個(gè)字符的小寫標(biāo)記。我們可以將分析器添加到一個(gè)或多個(gè)字段的索引中,也可以將其添加為標(biāo)準(zhǔn)分析器。

  1. client.CreateIndex("products", c => c 
  2.     // Analyzer added only for the property Description of Product 
  3.     .AddMapping<Product>(e => e 
  4.         .MapFromAttributes() 
  5.         .Properties(p => p.String(s => s.Name(f => f.Description) 
  6.         .Analyzer("product-analyzer"))) 
  7.     ) 
  8.     //Analyzer added as default 
  9.         .Analysis(analysis => analysis 
  10.             .Analyzers(a => a 
  11.             .Add("default", an) 
  12.         ) 
  13.     ) 

創(chuàng)建自定義分析器時(shí),可以使用測(cè)試API對(duì)其進(jìn)行測(cè)試。即使對(duì)于默認(rèn)分析儀,也可以執(zhí)行這些測(cè)試。

  1. var analyzeResponse = client.Indices.Analyze(a => a 
  2.     .Tokenizer("standard"
  3.     .Filter("lowercase""stop"
  4.     .Text("Lorem ipsum dolor sit amet, consectetur..."
  5. ); 

我們還可以使用數(shù)據(jù)聚合來提供通過搜索查詢聚合的數(shù)據(jù),它基于可以組成以獲得復(fù)雜聚合的簡單塊。聚合有不同類型,每種類型都有定義的范圍和輸出。它們可以分為:

  • 桶裝:具有關(guān)鍵和標(biāo)準(zhǔn)的容器;
  • 指標(biāo):根據(jù)一組文檔計(jì)算的指標(biāo);
  • 矩陣:在不同文檔字段上進(jìn)行的一系列操作,以矩陣樣式生成數(shù)據(jù);
  • 管道:更多聚合的聚合。

在我們的案例中,我們使用匯總來獲取品牌,類別,價(jià)格范圍的產(chǎn)品數(shù)量。在以下示例中,我們找到了產(chǎn)品價(jià)格的匯總:

  1. s => s 
  2.     .Query(...) 
  3.     .Aggregations(aggs => aggs 
  4.         .Average("average_price"avg => avg.Field(p => p.Price)) 
  5.         .Max("max_price"avg => avg.Field(p => p.Price)) 
  6.         .Min("min_price"avg => avg.Field(p => p.Price)) 
  7.     ) 

另一個(gè)有用的聚合是根據(jù)品牌,商店或類別進(jìn)行分組:

  1. s => s 
  2.      .Query(...) 
  3.      .Aggregations(aggs => aggs 
  4.          .ValueCount("products_for_category"avg => avg.Field(p => p.Category.Name)) 
  5.          .ValueCount("products_for_brand"avg => avg.Field(p => p.Brand.Name)) 
  6.          .ValueCount("products_for_store"avg => avg.Field(p => p.Store.Name)) 
  7.      ) 

這樣,我們可以實(shí)時(shí)獲取針對(duì)類別,品牌和商店的搜索產(chǎn)品數(shù)量。匯總數(shù)據(jù)還可以用于創(chuàng)建儀表板,甚至可以使用動(dòng)態(tài)過濾器(類似于電子商務(wù))來組織搜索,并且顯然可以用于統(tǒng)計(jì)目的。

改善您的搜索

如您所知,我們對(duì)任何搜索結(jié)果都有分?jǐn)?shù)。等級(jí)是從0到1的數(shù)字,它確定搜索參數(shù)如何接近該結(jié)果。得分主要取決于三個(gè)參數(shù):搜索詞的頻率,倒排文檔的頻率和字段長度。

要從得分中排除得分過低的人,我們可以使用MinScore:

  1. s => s 
  2.      .MinScore(0.5) 
  3.      .Query(...) 

這樣,我們可以排除分?jǐn)?shù)低于0.5的所有結(jié)果。建議者允許您使用與搜索文本相似的術(shù)語來搜索ElasticSearch索引。例如,完成建議器對(duì)于自動(dòng)完成很有用,它會(huì)在鍵入文本時(shí)引導(dǎo)您獲得最佳和更相關(guān)的結(jié)果。該完成建議程序經(jīng)過優(yōu)化,可以盡快返回結(jié)果,但是它使用啟用了快速查找的結(jié)構(gòu)并需要資源。

在我們的案例中,我們實(shí)現(xiàn)了基于產(chǎn)品名稱的自動(dòng)完成方法,該方法將在搜索框中鍵入以下內(nèi)容時(shí)被調(diào)用:

  1. s => s 
  2.     .Query(...) 
  3.     .Suggest(su => su 
  4.         .Completion("name", cs => cs 
  5.             .Field(f => f.Name
  6.             .Fuzzy(f => f 
  7.                 .Fuzziness(Fuzziness.Auto) 
  8.             ) 
  9.             .Size(5) 
  10.         ) 
  11.     ) 

更好的搜索的另一有用方法是索引boost。當(dāng)您搜索更多索引時(shí),可以為這些索引分配一個(gè)乘數(shù),這樣一來,一個(gè)索引的結(jié)果將比另一個(gè)顯示更多。您可以將其用于商業(yè)目的,與供應(yīng)商達(dá)成協(xié)議或使我們的產(chǎn)品脫穎而出。索引提升的一個(gè)示例是:

  1. s => s 
  2.     .Query(...) 
  3.     .IndicesBoost(b => b 
  4.         .Add("products-1", 1.5) 
  5.         .Add("products-2", 1) 
  6.     ) 

在此示例中,我們將乘數(shù)1.5乘以1的結(jié)果,乘以1乘以2的結(jié)果,這樣乘積1的結(jié)果將被更頻繁地顯示。改進(jìn)搜索的另一種方法是通過一些參數(shù)對(duì)它們進(jìn)行排序。就我們而言,我們可以:

  1. s => s 
  2.     .Query() 
  3.     .Sort(ss => ss 
  4.         .Descending(SortSpecialField.Score) 
  5.         .Descending(p => p.Price) 
  6.         .Descending(p => p.ReleaseDate) 
  7.         .Ascending(SortSpecialField.DocumentIndexOrder) 
  8.     ) 

我們將評(píng)分,價(jià)格,發(fā)布日期以及最終索引順序設(shè)置為更高的優(yōu)先級(jí)。

運(yùn)行項(xiàng)目

我們的示例項(xiàng)目是一個(gè).NET Core MVC WebApi應(yīng)用程序,該應(yīng)用程序提供一個(gè)搜索框和一個(gè)儀表板,其中的儀表板會(huì)根據(jù)鍵入的文本自動(dòng)刷新數(shù)據(jù)。首次運(yùn)行項(xiàng)目時(shí),我們可以加載由Bogus插件創(chuàng)建的n個(gè)Product對(duì)象。還有其他偽造類可以為品牌,類別,商店,評(píng)論和用戶構(gòu)建隨機(jī)對(duì)象。它允許您擁有一個(gè)數(shù)據(jù)庫來執(zhí)行我們的搜索。

  1. var productFaker = new Faker<Product>() 
  2.     .CustomInstantiator(f => new Product()) 
  3.         .RuleFor(p => p.Id, f => f.IndexFaker) 
  4.         .RuleFor(p => p.Ean, f => f.Commerce.Ean13()) 
  5.         .RuleFor(p => p.Name, f => f.Commerce.ProductName()) 
  6.         .RuleFor(p => p.Description, f => f.Lorem.Sentence(f.Random.Int(5, 20))) 
  7.         .RuleFor(p => p.Brand, f => f.PickRandom(brands)) 
  8.         .RuleFor(p => p.Category, f => f.PickRandom(categories)) 
  9.         .RuleFor(p => p.Store, f => f.PickRandom(stores)) 
  10.         .RuleFor(p => p.Price, f => f.Finance.Amount(1, 1000, 2)) 
  11.         .RuleFor(p => p.Currency, "€"
  12.         .RuleFor(p => p.Quantity, f => f.Random.Int(0, 1000)) 
  13.         .RuleFor(p => p.Rating, f => f.Random.Float(0, 1)) 
  14.         .RuleFor(p => p.ReleaseDate, f => f.Date.Past(2)) 
  15.         .RuleFor(p => p.Image, f => f.Image.PicsumUrl()) 
  16.         .RuleFor(p => p.Reviews, f => reviewFaker.Generate(f.Random.Int(0, 1000)) 
  17.     ) 

在頁面中間,有一個(gè)儀表板,我們?cè)谄渲惺褂昧吮疚慕榻B的過濾器,分析器和方法。在頂部的搜索框中鍵入一些文本時(shí),將建議相關(guān)產(chǎn)品,并且儀表板內(nèi)容將根據(jù)搜索文本進(jìn)行更新。

結(jié)論

在本文中,我向您展示了如何使用Elasticsearch對(duì)復(fù)雜的實(shí)際場(chǎng)景進(jìn)行有效的處理,分析和搜索數(shù)據(jù)。希望我對(duì)這個(gè)話題感興趣。

此處[2]提供了[3]帶有本文中使用的代碼的示例項(xiàng)目。

References

[1] 一篇文章中: https://www.blexin.com/en-US/Article/Blog/How-to-integrate-ElasticSearch-in-ASPNET-Core-70

[2] 此處: https://github.com/enricobencivenga/ProductElasticSearchAdvanced 

[3] 了: https://github.com/enricobencivenga/ProductElasticSearchAdvanced

 

責(zé)任編輯:武曉燕 來源: DotNET技術(shù)圈
相關(guān)推薦

2009-03-30 10:34:03

ASP.NETMySQL

2021-01-04 05:44:54

框架日志

2021-01-07 07:39:07

工具接口 Swagger

2021-01-31 22:56:50

FromServiceASP

2021-02-03 13:35:25

ASPweb程序

2021-03-03 22:37:16

MediatR中介者模式

2021-03-10 09:40:43

LamarASP容器

2021-02-28 20:56:37

NCache緩存框架

2021-01-28 22:39:35

LoggerMessa開源框架

2021-02-06 21:40:13

SignalR通訊TypeScript

2021-03-17 09:45:31

LazyCacheWindows

2021-02-02 16:19:08

Serilog日志框架

2017-04-21 12:03:46

MacASP.NET Cor程序

2021-02-07 17:29:04

監(jiān)視文件接口

2021-11-01 14:52:38

ElasticSear索引SQL

2021-01-26 14:57:00

中間件應(yīng)用模塊化

2021-04-12 07:03:10

輕量級(jí)模塊化框架

2021-06-22 16:59:56

微軟.NETC# 軟件開發(fā)

2013-03-25 10:38:24

ASP.NETHttpModule

2012-03-07 09:08:00

HTML 5
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)