在.Net環境下使用elasticsearch實現大數據量的搜索


最近因為項目需要使用搜索引擎,因此嘗試使用.Net去操作elasticsearch,把使用過程記錄如下:

 

elasticsearch下文使用簡稱ES,ES已經更新到了6.*,經常使用的應該是2.*和5.*,其中5.*當然對2.*更新了許多功能,但是在初學者最直觀的改變是關聯插件的版本,2.*關聯插件的版本號基本上是亂的,需要去插件對應的網站上查詢,但是5.*對應的插件版本基本上和ES本身的版本號一致,這就避免了為找相應插件而做的很多無謂的工作。

 

1.安裝elasticsearch

1.1 安裝之前的准備

1)Jdk  ES是需要java環境的,因此需要Jdk,並配置環境變量,我在這里使用的版本是 1.8

2)Tomcat  esheader插件在使用時需要運行在Tomcat環境下,我這里使用的版本是 8.5.37

上面兩部分的安裝不再詳述

1.2 安裝ES

我這里使用的是5.6.0版本。下載路徑如下 ES 5.6.0下載

下載完成后,將下載文件直接解壓到安裝目錄下即可。

安裝完成后,就是啟動ES在bin目錄下可以運行elasticsearch.bat在命令行界面啟動(命令行不能關閉),也可以運行elasticsearch-service.bat啟動ES的服務進程,這樣就不用每次開機啟動了。

配置文件在config/elasticsearch.yml中,每次修改完配置需要服務重啟,切記切記。

 

啟動成功后,打開瀏覽器,輸入默認的url和端口  

http://localhost:9200/   

如果啟動成功,則會出現如下頁面,說明安裝成功了

ES的一些關鍵概念,可以參考:ES關鍵概念

2.安裝elasticsearch插件

ES有許多插件用來幫助我們使用,其中我覺得最主要的有兩個插件

 1)esheader    可以使用在web頁面上訪問esheader的集群數據

 2)  analysis-ik   中文的分詞插件,默認的分詞功能在搜索時只能將中文分成一個一個的單字

 

2.1 esheader的安裝

esheader在2.*版本上是可以直接在命令行中進行安裝的,但是5.*版本上不能這樣做了,網上采用的辦法很麻煩,我找到一種比較簡單的辦法。

首先下載esheader文件,下載路徑如下 esheader下載 。

其實說到底esheader就是在web頁面上向es服務器發送http請求,並獲取結果進行展示,其實esheader實質上就是一個java web網站,因此只需要將它部署到tomcat服務器上,運行即可。

ip和端口號,需要和安裝ES配置的相一致,而且需要將ES的配置文件修改為允許跨域訪問即在config/elasticsearch.yml最后追加如下配置,然后重啟服務

http.cors.enabled: true
http.cors.allow-origin: "*"

然后訪問tomcat上對應的網頁即可,如下圖。說明esheader安裝成功了!!

2.2 analysis-ik 的安裝

ik可以直接在命令行下面安裝(前提是知道ik文件的url)

在ES的bin目錄下打開控制台運行 ,即可

.\elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.6.0/elasticsearch-analysis-ik-5.6.0.zip

 安裝完成后ES的plugins目錄中會添加對應插件的目錄

 

3.使用NEST訪問ES

新建一個.net控制台項目,打開NuGet管理器,搜索NEST,然后安裝,如圖。我安裝的是5.6.0版本,不知道其余版本是否OK,感興趣的朋友可以試試

 

安裝完成后,就可以編寫代碼了

        private static void AddData()
        {
            //1.通過es服務器 localhost:9200 來定義es client
            var node = new Uri("http://localhost:9200");
            var indexName = "products";
            var settings = new ConnectionSettings(node).DefaultIndex(indexName);
            var elastic = new ElasticClient(settings);

            //es服務器健康檢查
            var res = elastic.ClusterHealth();
            Console.WriteLine(res.Status);

            //2.創建索引esbot
            //if (!elastic.IndexExists(indexName).Exists)
            //{
            //    var createIndexResponse = elastic.CreateIndex(indexName);
            //    var mappingBlogPost = elastic.Map<Account>(s => s.AutoMap());
            //}
            //var mappingBlogPost = elastic.Map<Account>(s => s.AutoMap());
            //List<Account> accounts = new List<Account>() { new Account { Id = 2, Name = "aaa", Password = "bbb" }, new Account { Id = 3, Name = "ccc", Password = "ddd" } };
            List<Product> duodians = new TestEntities().duodian.ToList().Select(a => a.ToProduct()).ToList();


            elastic.IndexMany(duodians, indexName);

        }

        private static void SimpleSelect()
        {
            //1.通過es服務器 localhost:9200 來定義es client
            var node = new Uri("http://localhost:9200");
            var indexName = "products";
            var settings = new ConnectionSettings(node).DefaultIndex(indexName);
            var elastic = new ElasticClient(settings);

            //5. 簡單搜索
            //var searchResult = elastic.Search<Product>(sr => sr.Query(q => q.MatchAll()).From(0).Size(100));
            //var searchResult = elastic.Search<Product>(sr => sr.Query(q => q.QueryString(qs=>qs.Query("蘇泊爾"))));
            var searchResult = elastic.Search<Product>(sr => sr.Query(q => q.Match(qm => qm.Field(f => f.title).Query("給你省小號擀面杖"))));

            return;
        }
View Code

 

    [ElasticsearchType(Name = "Product", IdProperty = "GuidId")]
    public class Product
    {
        [Keyword(Name = "GuidId", Index = true)]
        public string GuidId { get; set; } = Guid.NewGuid().ToString();

        [Number(NumberType.Long, Name = "Id")]
        public int id { get; set; }

        [Text(Name = "Title", Index = true, Analyzer = "ik_max_word")]
        public string title { get; set; }

        [Keyword(Name = "Img", Index = false)]
        public string img { get; set; }

        [Keyword(Name = "Lunfanimg", Index = false)]
        public string lunfanimg { get; set; }

        [Keyword(Name = "Spec", Index = false)]
        public string spec { get; set; }

        [Keyword(Name = "Xcimg", Index = false)]
        public string xcimg { get; set; }

        [Keyword(Name = "Skuid", Index = false)]
        public string skuid { get; set; }

        [Keyword(Name = "Pimg", Index = false)]
        public string pimg { get; set; }

        [Keyword(Name = "Plunfanimg", Index = false)]
        public string plunfanimg { get; set; }

        [Keyword(Name = "Pxcimg", Index = false)]
        public string pxcimg { get; set; }

        [Keyword(Name = "Categoryid", Index = false)]
        public string categoryid { get; set; }

        [Keyword(Name = "Price", Index = false)]
        public string price { get; set; }

        [Keyword(Name = "Brandname", Index = false)]
        public string brandname { get; set; }

        [Keyword(Name = "Categoryname", Index = false)]
        public string categoryname { get; set; }

        [Keyword(Name = "Created", Index = false)]
        public System.DateTime created { get; set; }
    }

    public static class duodianExtension
    {
        public static Product ToProduct(this duodian duodian)
        {
            return new Product
            {
                brandname = duodian.brandname,
                categoryid = duodian.categoryid,
                id = duodian.id,
                img = duodian.img,
                lunfanimg = duodian.lunfanimg,
                pimg = duodian.pimg,
                plunfanimg = duodian.plunfanimg,
                price = duodian.price,
                pxcimg = duodian.pxcimg,
                skuid = duodian.skuid,
                spec = duodian.spec,
                title = duodian.title,
                xcimg = duodian.xcimg,
                created = duodian.created,
                categoryname = duodian.categoryname
            };
        }
    }
View Code

 

個人感覺在web項目中使用該框架的難點在於,需要定時將數據表的數據與ES進行同步,至於同步的時機和頻率,希望在之后的項目中能夠了解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM