1. 程式人生 > >.NET 分散式 搜尋 elasticsearch.net NEST

.NET 分散式 搜尋 elasticsearch.net NEST

我們公司(電商)目前使用 elasticsearch。對於一個3億資料量索引查詢速度都是在毫秒級別,不過實現都是基於Java的client. 本人因為是.NET出身,雖然現在做JAVA。但是對.NET情有獨鍾。所以閒暇時間研究了下 elasticsearch的.NET 的CLIENT的NEST.希望.NET人員多使用 elasticsearch 來做搜尋服務 解決.NET一直沒有好的搜尋服務。本人以前也研究過 Lucene.NET。但是無法實現叢集及分散式。

本人也參考了很多前輩部落格和和本公司做搜尋的同事 和 google。走了很多彎路。所以希望後來人別走很多彎路。

Elasticsearch一般至少最少3臺服務。2臺伺服器時候1一臺是主分片。另外一臺永遠都是副本所以在服務,無法實現叢集式搜尋。只能實現主從備份模式。

所以伺服器建議3臺以上。這樣分片才會平衡到3臺伺服器上。

參考資料

安裝Elasticsearch

網上已經有很多資料了。所以這裡不再寫了

1、VS2012安裝NEST

PM> Install-Package NEST -version 1.7.2

我安裝的是1.7.2的客戶端版本。

2、建立連線

 public  static ElasticClient GetElasticClient(string indexName)
        {
            var connectString = "http://127.0.0.1:9200";
            var
nodesStr = connectString.Split('|'); var nodes = nodesStr.Select(s => new Uri(s)).ToList(); var connectionPool = new SniffingConnectionPool(nodes); var settings = new ConnectionSettings(connectionPool); if (!string.IsNullOrWhiteSpace(indexName)) { settings.SetDefaultIndex(indexName); } var
client = new ElasticClient(settings); return client; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3、建立索引

建立索引只需要呼叫一次即可。

 索引結構如下:
[ElasticType(IdProperty = "id", Name = "order")]
public class Order
{
 [ElasticProperty(Name = "id", Type = FieldType.Long, Index = FieldIndexOption.NotAnalyzed)]
  public long Id { get; set; }


public string Content { get; set; }
[ElasticProperty(Name = "firstname", Type = FieldType.String, Index = FieldIndexOption.Analyzed)]
public string Firstname { get; set; }

[ElasticProperty(Name = "lastname", Type = FieldType.String, Index = FieldIndexOption.NotAnalyzed)]
public string Lastname { get; set; }


 [ElasticProperty(Name = "totalprice", Type = FieldType.Double, Index = FieldIndexOption.NotAnalyzed)]
public Double TotalPrice { get; set; }

[ElasticProperty(Name = "createtime", Type = FieldType.Date, Index = FieldIndexOption.Analyzed)]
public DateTime Createtime { get; set; }

    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

[ElasticType(IdProperty = “id”, Name = “order”)]

這個IdProperty欄位屬性是搜尋在做分片時候需要HASH物件。所以選擇這個可以根據資料庫的分割槽鍵或者資料庫主鍵來選擇具體哪個欄位來做IdProperty。一般都是選擇資料庫主鍵

Content:這個欄位未定義屬性。 所以這個欄位不能拿來做查詢條件。

要做查詢條件的欄位都必須加上

[ElasticProperty(Name = “lastname”, Type = FieldType.String, Index = FieldIndexOption.NotAnalyzed)] 
或者

[ElasticProperty(Name = “createtime”, Type = FieldType.Date, Index = FieldIndexOption.Analyzed)]

這兩個的區別是 
NotAnalyzed 是不分詞只做索引欄位

Analyzed 作為查詢欄位並且分詞

所以建立索引必須規劃好每個欄位是否分詞及是否查詢。

      /// <summary>
        /// 建立索引
        /// </summary>
        /// <param name="indexName"></param>
        private static void CreateIndex(string indexName)
        {

            var client = ElasticsearchHelper.GetElasticClient("");
            //client 不能給 default
            client.CreateIndex(r => r.Index(indexName).NumberOfReplicas(1).NumberOfShards(20));
            client.Map<Order>(m => m.MapFromAttributes()); 
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

這裡是建立ORDER的索引並且每個分片一個副本 總共20個分片。

20分片實際要根據業務資料量多少來決定。

4、刪除索引

      /// <summary>
        /// 刪除索引
        /// </summary>
        private static void DeleteIndex()
        {
            var client = ElasticsearchHelper.GetElasticClient("order");
            var result = client.DeleteIndex(r => r.Index("order"));
            System.Console.WriteLine(result.IsValid);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5、寫入資料

    private static  void WriteIndex()
        {
            var client = ElasticsearchHelper.GetElasticClient("order");
            long i = GetMax();
            while (true)
            {
                i++;
                SetMax(i);
                Order order = new Order()
                {
                    Id = i,
                    Firstname = "我愛天安門",
                    Lastname = "外派",
                    TotalPrice =Convert.ToDouble(i),
                    Content = "天使3412341234" + i.ToString(),
                    Createtime = DateTime.Now
                };
                var addResult = client.Index(order);
                System.Console.WriteLine("第" + i + "行記錄" + addResult.Created);

            }

        }

        static long GetMax()
        {
            long reslt = 0;
            try
            {
                string k = System.IO.File.ReadAllText("1.txt");
                reslt = Convert.ToInt64(k);
            }
            catch (Exception)
            {

            }
            return reslt;
        }

        static long SetMax(long max)
        {
            long reslt = 0;
            try
            {
                System.IO.File.WriteAllText("1.txt", max.ToString());
            }
            catch (Exception)
            {

            }
            return reslt;
        }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

6、查詢

#region 求和
var client = ElasticsearchHelper.GetElasticClient("order");
QueryContainer termQuery = new TermQuery() { Field = "lastname", Value = "求和" };
var result = client.Search<Order>(s => s
                .Aggregations(a => a
                    .Sum("my_sum_agg", sa => sa
                        .Field(p => p.TotalPrice)
                    )
                )
            );
var agg = result.Aggs.Sum("my_sum_agg");


var searchResults = client.Search<Order>(s => s
              //  .Query(termQuery)  //帶篩選條件
                .Aggregations(r => r.Terms("firstname", r1 => r1.Field(r2 => r2.Lastname)
                    .OrderAscending("sumprice")
                    .Aggregations(y => y.Sum("sumprice", y1 => y1.Field(y2 => y2.TotalPrice))))));

var carTypes = searchResults.Aggs.Terms("firstname");
            List<double> re=new List<double>();
            foreach (var carType in carTypes.Items)
            {
                string key = carType.Key;
                System.Console.WriteLine("key:" + key + " total:" + carType.Sum("sumprice").Value);
                re.Add((double)carType.Sum("sumprice").Value);
            }
            //List<SumTotalPrice> orders = searchResults.Documents.ToList();
         //   System.Console.WriteLine(orders.Count() + " total:" + searchResults.Total);
            //System.Console.WriteLine(searchResults.RequestInformation);
            System.Console.ReadLine();

            #endregion


  #region 多條件精確匹配
            var client = ElasticsearchHelper.GetElasticClient("order");
            QueryContainer termQuery = new TermQuery() { Field = "firstname", Value = "測試" };
            QueryContainer wholeWordQuery = new TermQuery() { Field = "lastname", Value = "addddd" };
            //非索引欄位。無法查詢 此查詢條件無效
            QueryContainer termQuery1 = new TermQuery() { Field = "content", Value = "  天空是百度的1696" };
            termQuery = (termQuery || wholeWordQuery) || termQuery1;

            var searchResults = client.Search<Order>(s => s
                .From(0)
                .Size(10)
                .Query(termQuery)
                );
            List<Order> orders = searchResults.Documents.ToList();
            System.Console.WriteLine(orders.Count() + " total:" + searchResults.Total);
            System.Console.ReadLine();

            #endregion

               #region 精確匹配
            var client = ElasticsearchHelper.GetElasticClient("order");
            var searchResults = client.Search<Order>(s => s
              .From(0)
              .Size(10)
              .Query(q => q.Term(r => r.OnField(k => k.Firstname).Value("棉花")))
              .Highlight(h => h.OnFields(e => e.OnField("firstname")
                                .PreTags("<b style='color:black'>")
                                .PostTags("</b>")))
              .Sort(r => r.Descending().OnField(q => q.Createtime))
              );
            List<Order> orders = searchResults.Documents.ToList();

            System.Console.WriteLine(orders.Count() + " total:" + searchResults.Total);
            System.Console.ReadLine();

            #endregion

          //  //查詢索引欄位 帶 褲的  類似 資料庫的  like '褲%'
            var client = ElasticsearchHelper.GetElasticClient("order");
            var searchResults = client.Search<Order>(s => s
          .From(0)
          .Size(10)
          .QueryString("褲*")
          );
            System.Console.WriteLine(" total:" + searchResults.Total);
            System.Console.ReadLine();


            #region ID查詢

            var searchResults = client.Search<Order>(s => s
               .From(0)
               .Size(10)
               .Query(q => q.Ids(r=>r.Values(19)))
               );

            #endregion

 #region 時間範圍查詢
            var client = ElasticsearchHelper.GetElasticClient("order");
          //  QueryContainer termQuery = new TermQuery() { Field = "firstname", Value = "測試" };
            var format = "yyyy-MM-dd'T'HH:mm:ss.fff+08:00";
            var lowerBound = DateTime.Now.AddMinutes(-20);

            var searchResults = client.Search<Order>(s => s
               // .Query(r => termQuery && r.Range(st => st.OnField(st1 => st1.Createtime).GreaterOrEquals(lowerBound, format)))
                .Query(r => r.Range(st => st.OnField(st1 => st1.Createtime).GreaterOrEquals(lowerBound, format)))
                .SortDescending(r=>r.Createtime)
                .From(0)
                .Size(10)
                );
            List<Order> orders = searchResults.Documents.ToList();
             var k=  searchResults.RequestInformation;
            System.Console.WriteLine(orders.Count() + " total:" + searchResults.Total);
            System.Console.ReadLine();

            #endregion



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

7、刪除資料

     private static  void DeleteRowById(long id)
        {
            var client = ElasticsearchHelper.GetElasticClient("order");

            client.Delete<Order>(r => r.Id(id));

        }
轉載自:http://blog.csdn.net/kingson88/article/details/51252606

相關推薦

.NET 分散式 搜尋 elasticsearch.net NEST

我們公司(電商)目前使用 elasticsearch。對於一個3億資料量索引查詢速度都是在毫秒級別,不過實現都是基於Java的client. 本人因為是.NET出身,雖然現在做JAVA。但是對.NET情有獨鍾。所以閒暇時間研究了下 elasticsearch的.NET

分散式搜尋Elasticsearch——刪除指定索引

      刪除索引的方式很多,這裡列舉三種。       第一種是指定index、type、id執行刪除,示例程式碼如下: /** * @author Geloin */ package com.gsoft.gsearch.util; import org.elas

分散式搜尋elasticsearch java API 之 highlighting (對搜尋結果的高亮顯示)

搜尋請求的Body如下:: { "query" : {...}, "highlight" : { "fields" : { "title":{}, "intro" : {}

分散式搜尋elasticsearch 基本概念

ElasticSearch官網:http://www.elasticsearch.org/ 先上一張elasticsearch的總體框架圖: ElasticSearch是基於Lucene開發的分散式搜尋框架,包含如下特性: 分散式索引、搜尋 索引自動分片、負載均衡 自動

分散式搜尋elasticsearch java API 之(六)------批量新增刪除索引

elasticsearch支援批量新增或刪除索引文件,java api裡面就是通過構造BulkRequestBuilder,然後把批量的index/delete請求新增到BulkRequestBuilder裡面,執行BulkRequestBuilder。下面是個例子: im

分散式搜尋elasticsearch配置檔案elasticsearch.yml詳解

配置檔案位於%ES_HOME%/config/elasticsearch.yml檔案中,用Editplus開啟它,你便可以進行配置。        所有的配置都可以使用環境變數,例如:node.rack: ${RACK_ENV_VAR}        表示環境變數中有一個R

分散式搜尋Elasticsearch——QueryBuilders.matchPhrasePrefixQuery

        ES源代碼中對matchPhrasePrefixQuery的描述如下所示: /** * Creates a match query with type "PHRASE_PREFIX" for the provided field nam

分散式搜尋elasticsearch java API 之(八)------使用More like this實現基於內容的推薦

基於內容的推薦通常是給定一篇文件資訊,然後給使用者推薦與該文件相識的文件。Lucene的api中有實現查詢文章相似度的介面,叫MoreLikeThis。Elasticsearch封裝了該介面,通過Elasticsearch的More like this查詢介面,我們可以非常

分散式搜尋Elasticsearch——QueryBuilders.matchPhraseQuery

        ES源代碼中對matchPhraseQuery的描述如下所示: /** * Creates a text query with type "PHRASE" for the provided field name and text.

分散式搜尋elasticsearch 搜尋結果排序不一致性問題

想象這一種情況,如果搜尋結果中得分出現相同的情況下:由於搜尋會在分片的副本之間均衡的輪詢請求,可能會出現請求在不同的副本之間返回的循序不同,從而影響排序結果的穩定性。 搜尋介面有提供preference引數:curl localhost:9200/_search?prefe

ASP.NET Web API + Elasticsearch 6.x 快速做個全文搜尋

最近想做個全文搜尋,設想用 ASP.NET Web API + Elasticsearch 6.x 來實現。 網上搜了下 Elasticsearch 的資料,大部分是講 linux 平臺下如何用 java 來開發,有少量講在 windows 平臺下用 c# 開發的,且版本是 Elasti

Elasticsearch.Net Nest 5.0.0 用法

1:引用dll using Elasticsearch.Net; using Nest; 2:程式碼(如下程式碼是查詢以及建立index的基本用法,包含模糊查詢和精確查詢) var node = new Uri("http://localhost:9

elasticsearch.net search入門使用指南中文版(翻譯)

per set option 數量 允許 工具 hapi bsp smart elasticsearch.net search入門使用指南中文版,elasticsearch.Net是一個非常底層且靈活的客戶端,它不在意你如何的構建自己的請求和響應。它非常抽象,因此所有的el

Fire Net —— dfs搜尋

Fire Net Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a

ASP.NET Core使用Elasticsearch記錄NLog日誌

ASP.NET Core使用Elasticsearch記錄NLog日誌 1、新建一個 ASP.NET Core專案   2、安裝Nuge包 執行:Install-Package NLog.Web.AspNetCore 執行:Install-Package NLog 執行:Inst

Elasticsearch 6.5.3 釋出,分散式搜尋和資料分析引擎

   Elasticsearch 6.5.3 釋出了,Elasticsearch 是一個分散式的 RESTful 風格的搜尋和資料分析引擎。 更新如下: Enhancements Engine Always configure soft-deletes field of I

Elasticsearch.net專案實戰

elasticsearch.net專案實戰 @智客幸達 目錄 Elasticsearch+kibana 環境搭建 windows 10環境配置 安裝Elasticsearch head安裝(非必需) 安裝kibana DSL的基本使用 增加 修改 查詢 刪除 Elasticsearch .N

大資料篇:Elasticsearch分散式搜尋與分析引擎

Elasticsearch簡介 Elasticsearch是一個實時的分散式搜尋和分析引擎。它可以幫助你用前所未有的速度去處理大規模資料。 它可以用於全文搜尋,結構化搜尋以及分析,當然你也可以將這三者進行組合。 Elasticsearch是一個建立在全文搜尋引擎 Apa

Elasticsearch.Net 官網示例的坑

  經過昨天的ElasticSearch 安裝,服務以及可以啟動了,接下來就可以開發了,找到了官網提供的API以及示例,Es 官方提供的.net 客戶端有兩個版本一個低階版本: 【Elasticsearch.Net.dll】這個dll檔案官方解釋無依賴關係的客戶端,對於您如何構建和表示您的請求和相應沒有任何意

ASP.NET Web API + Elasticsearch 6.x 快速做個全文搜索

工程 數據 希望 div ogr cti 完成 環境 包管理器 最近想做個全文搜索,設想用 ASP.NET Web API + Elasticsearch 6.x 來實現。 網上搜了下 Elasticsearch 的資料,大部分是講 linux 平臺下如何用 java 來開