成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何在我們的Asp.NET Core應用程序中使用ElasticSearch高級功能

開發 后端
在本文中,我向您展示了如何使用Elasticsearch對復雜的實際場景進行有效的處理,分析和搜索數據。希望我對這個話題感興趣。

[[432709]]

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

今天,我們仍然要在電子商務網站中向您展示如何使用ElasticSearch的許多功能來改善搜索。

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

我們的模型產品類別已變為:

  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; } 

其中品牌,類別,商店評論和用戶類別分別是:

  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庫中用于地理數據的類。產品索引已被簡單地命名為產品。我們以這種方式創建和配置了它:

  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索引創建一個名為fullname的新屬性,用于名為fullname的User類,并定義了將要處理的地理信息。 為了使我們的產品能夠在索引之前進行處理,一種有用的方法是node.ingest,即進行文檔預處理的節點。接收節點攔截所有索引請求,甚至是批量索引請求,并將所有定義的轉換應用于其內容,然后將文檔發還給索引API。

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

啟用node.ingest:

  1. node.ingest: true 

在我們的示例中,我們使用相同的節點進行搜索和攝取,我們不需要編寫代碼來管理攝取節點,但是,如果我們要擁有一組專用的攝取節點,則必須配置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); 

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

  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將包含名字和姓氏(設置攝取);
  • User.IPAddress將成為地理定位的地理地址(GeoIp提取)。

管道以ElasticSearch集群狀態保存,要使用它們,您必須在索引請求中指定管道參數,以便攝取節點知道必須使用哪個管道:

  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. ); 

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

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

分析儀由三個主要部分組成:

1.0個或多個字符過濾器

2.1個分詞器

3.0個或多個令牌過濾器

有一些默認的分析器可以使用,但是,為了根據我們的要求提高搜索的準確性,我們創建了一個自定義分析器。

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

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

  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); 

我們的分析器使用標準的標記化方法,創建3至15個字符的小寫標記。我們可以將分析器添加到一個或多個字段的索引中,也可以將其添加為標準分析器。

  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.     ) 

創建自定義分析器時,可以使用測試API對其進行測試。即使對于默認分析儀,也可以執行這些測試。

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

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

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

在我們的案例中,我們使用匯總來獲取品牌,類別,價格范圍的產品數量。在以下示例中,我們找到了產品價格的匯總:

  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.     ) 

另一個有用的聚合是根據品牌,商店或類別進行分組:

  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.      ) 

這樣,我們可以實時獲取針對類別,品牌和商店的搜索產品數量。匯總數據還可以用于創建儀表板,甚至可以使用動態過濾器(類似于電子商務)來組織搜索,并且顯然可以用于統計目的。

改善您的搜索

如您所知,我們對任何搜索結果都有分數。等級是從0到1的數字,它確定搜索參數如何接近該結果。得分主要取決于三個參數:搜索詞的頻率,倒排文檔的頻率和字段長度。

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

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

這樣,我們可以排除分數低于0.5的所有結果。建議者允許您使用與搜索文本相似的術語來搜索ElasticSearch索引。例如,完成建議器對于自動完成很有用,它會在鍵入文本時引導您獲得最佳和更相關的結果。該完成建議程序經過優化,可以盡快返回結果,但是它使用啟用了快速查找的結構并需要資源。

在我們的案例中,我們實現了基于產品名稱的自動完成方法,該方法將在搜索框中鍵入以下內容時被調用:

  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。當您搜索更多索引時,可以為這些索引分配一個乘數,這樣一來,一個索引的結果將比另一個顯示更多。您可以將其用于商業目的,與供應商達成協議或使我們的產品脫穎而出。索引提升的一個示例是:

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

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

  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.     ) 

我們將評分,價格,發布日期以及最終索引順序設置為更高的優先級。

運行項目

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

  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.     ) 

在頁面中間,有一個儀表板,我們在其中使用了本文介紹的過濾器,分析器和方法。在頂部的搜索框中鍵入一些文本時,將建議相關產品,并且儀表板內容將根據搜索文本進行更新。

結論

在本文中,我向您展示了如何使用Elasticsearch對復雜的實際場景進行有效的處理,分析和搜索數據。希望我對這個話題感興趣。

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

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

 

責任編輯:武曉燕 來源: DotNET技術圈
相關推薦

2009-03-30 10:34:03

ASP.NETMySQL

2021-01-04 05:44:54

框架日志

2021-03-10 09:40:43

LamarASP容器

2021-02-03 13:35:25

ASPweb程序

2021-02-28 20:56:37

NCache緩存框架

2021-01-07 07:39:07

工具接口 Swagger

2021-03-03 22:37:16

MediatR中介者模式

2021-01-28 22:39:35

LoggerMessa開源框架

2021-01-31 22:56:50

FromServiceASP

2021-03-17 09:45:31

LazyCacheWindows

2021-02-06 21:40:13

SignalR通訊TypeScript

2021-02-02 16:19:08

Serilog日志框架

2017-04-21 12:03:46

MacASP.NET Cor程序

2021-02-07 17:29:04

監視文件接口

2021-11-01 14:52:38

ElasticSear索引SQL

2021-06-22 16:59:56

微軟.NETC# 軟件開發

2021-01-26 14:57:00

中間件應用模塊化

2021-04-12 07:03:10

輕量級模塊化框架

2013-03-25 10:38:24

ASP.NETHttpModule

2012-03-07 09:08:00

HTML 5
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 毛片a级| 欧美日韩在线精品 | 欧美日韩成人网 | 91精品国产色综合久久不卡蜜臀 | 91精品国产91久久久久久最新 | 国产性网 | 久久亚洲春色中文字幕久久久 | 国产亚洲欧美日韩精品一区二区三区 | 欧美亚洲视频在线观看 | 人人干人人超 | 欧洲亚洲一区 | 伊人网影院 | 99热国产精品 | 在线观看日本高清二区 | 免费在线成人网 | 成人一区二区在线 | 在线观看h视频 | 国产9999精品 | 日韩不卡视频在线观看 | 日本大香伊一区二区三区 | 久久久国产精品一区 | 国产成人久久精品一区二区三区 | 欧美一级二级三级视频 | 91久久国产综合久久 | 久久精品视频一区二区三区 | 激情网五月天 | 中文字幕一区在线观看视频 | 国产精品夜间视频香蕉 | 亚洲综合大片69999 | 天天天天操 | 欧美成人二区 | 成人精品久久 | 一级黄色毛片免费 | 午夜在线小视频 | 日韩精品1区2区3区 成人黄页在线观看 | 欧美一区二区三区小说 | 成人免费看片 | 天天干.com | 亚洲欧美中文日韩在线v日本 | 亚洲欧美中文日韩在线v日本 | 日韩在线观看网站 |