NEST - 編寫查詢

来源:https://www.cnblogs.com/WessonStar/archive/2018/01/21/8323873.html
-Advertisement-
Play Games

Writing queries Version:5.x 英文原文地址: "Writing queries" 將數據索引到了 Elasticsearch 之後,就可以準備搜索它們了。Elasticsearch 提供了一個強大的查詢 DSL ,使得用戶可以定義個性化的搜索邏輯。這個 DSL 是基於 JS ...


Writing queries

Version:5.x

英文原文地址:Writing queries

將數據索引到了 Elasticsearch 之後,就可以準備搜索它們了。Elasticsearch 提供了一個強大的查詢 DSL ,使得用戶可以定義個性化的搜索邏輯。這個 DSL 是基於 JSON 的,NEST 提供了 Fluent API 和 Object Initializer 語法來實現 DSL 。

Match All query

最簡單的查詢應該就是 match_all 了,這種查詢會返回所有的文檔,並給每份文檔的 _score 統一賦值為 1.0

匹配的文檔並不是都會在一次響應中全部返回,預設情況下只返回前十份。你可以使用 fromsize 來將結果分頁

var searchResponse = client.Search<Project>(s => s
    .Query(q => q
        .MatchAll()
    )
);

上面的請求會被序列化成下麵這個 JSON 對象

{
  "query": {
    "match_all": {}
  }
}

由於 match_all 查詢很常見,因此前面的慄子有一個簡單的寫法,兩種方式序列化的結果是一樣的

searchResponse = client.Search<Project>(s => s
    .MatchAll()
);

前面的兩個慄子都是使用 Fluent API 來描述查詢。NEST 還公開了一種 Object Initializer 語法去構造查詢

var searchRequest = new SearchRequest<Project>
{
    Query = new MatchAllQuery()
};

searchResponse = client.Search<Project>(searchRequest);

Search request parameters

search request 有一些可用的參數,你可以參閱 search 以獲得詳細的信息。

Common queries

預設情況下,文檔會根據 _score 降序返回。每個命中的 _score 是根據文檔和查詢條件的匹配程度計算的關聯分數。數字越大,表示越符合查詢條件。

NEST 提供了許多搜索查詢,它們都記錄在 Query DSL 參考部分。在這裡,我們要強調用戶經常執行的三類查詢操作

  • Structured search
  • Unstructured search
  • Combining queries

結構化搜索是指,查詢具有固定結構的數據。日期、時間和數字都是結構化的,查詢這些類型的欄位通常是為了查找準確的匹配項、某個範圍內的值等等。文本也可以結構化,比如博客里使用的關鍵字標簽。

通過結構化搜索,查詢的答案總是 “是” 或者 “否”。也就是說,文檔要麼匹配查詢,要麼就不匹配。

術語級別的查詢通常用於結構化搜索。下麵的慄子查找開始日期在指定範圍內的文檔

var searchResponse = client.Search<Project>(s => s
    .Query(q => q
        .DateRange(r => r
            .Field(f => f.StartedOn)
            .GreaterThanOrEquals(new DateTime(2017, 01, 01))
            .LessThan(new DateTime(2018, 01, 01))
        )
    )
);

(1) 查找開始於 2017 年的所有的 Project

會生成以下查詢 JSON

{
  "query": {
    "range": {
      "startedOn": {
        "lt": "2018-01-01T00:00:00",
        "gte": "2017-01-01T00:00:00"
      }
    }
  }
}

因為這個查詢的答案只有 yesno 兩種情況,我自然就不需要給查詢計分了。為此,我們可以把這個查詢包裝在一個 bool 查詢 filter 子句中,這樣就可以讓查詢在篩選上下文中執行

searchResponse = client.Search<Project>(s => s
   .Query(q => q
       .Bool(b => b
           .Filter(bf => bf
               .DateRange(r => r
                   .Field(f => f.StartedOn)
                   .GreaterThanOrEquals(new DateTime(2017, 01, 01))
                   .LessThan(new DateTime(2018, 01, 01))
               )
           )
       )

   )
);
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "startedOn": {
              "lt": "2018-01-01T00:00:00",
              "gte": "2017-01-01T00:00:00"
            }
          }
        }
      ]
    }
  }
}

在篩選上下文中執行查詢的好處是,Elasticsearch 可以放棄計算相關性分數,還可以緩存篩選器從而獲得更快的後續性能

重要:術語級別的查詢沒有分析階段,也就是說不會分析查詢的輸入,進而在反向索引中尋找輸入的精確匹配。如果一個欄位在索引時進行了分析,那麼再通過術語級別查詢多半會失敗。

當欄位僅用於精確匹配時,應當考慮將其映射為 keyword 類型。如果欄位既用於精確匹配,又用於全文搜索,則應考慮將其映射為 multi fields

另一個常見的用例是,在全文欄位中搜索以查找最相關的文檔。

全文查詢用於非結構化的搜索。在這裡,我們使用 match 查詢來查找開發人員的名字中包含 “Russ” 的所有文檔

var searchResponse = client.Search<Project>(s => s
    .Query(q => q
        .Match(m => m
            .Field(f => f.LeadDeveloper.FirstName)
            .Query("Russ")
        )
    )
);

會生成以下查詢 JSON

{
  "query": {
    "match": {
      "leadDeveloper.firstName": {
        "query": "Russ"
      }
    }
  }
}

重要:全文查詢有分析階段。也就是說要分析查詢輸入,然後將分析後產生的術語和反向索引中的術語進行比較。

通過在映射期間給欄位設置分析器,你可以完全控制索引和搜索階段的分析過程。

Combining queries

一個非常常見的情況是,將不同的查詢組合在一起形成一個複合查詢。其中最常見的是 bool 查詢

var searchResponse = client.Search<Project>(s => s
    .Query(q => q
        .Bool(b => b
            .Must(mu => mu
                .Match(m => m (1)
                    .Field(f => f.LeadDeveloper.FirstName)
                    .Query("Russ")
                ), mu => mu
                .Match(m => m (2)
                    .Field(f => f.LeadDeveloper.LastName)
                    .Query("Cam")
                )
            )
            .Filter(fi => fi
                 .DateRange(r => r
                    .Field(f => f.StartedOn)
                    .GreaterThanOrEquals(new DateTime(2017, 01, 01))
                    .LessThan(new DateTime(2018, 01, 01)) (3)
                )
            )
        )
    )
);

(1) 匹配開發人員的名字包含 Russ 的所有文檔

(2) ... 並且開發人員的姓氏包含 Cam

(3) ... 並且項目開始於 2017

會生成以下查詢 JSON

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "leadDeveloper.firstName": {
              "query": "Russ"
            }
          }
        },
        {
          "match": {
            "leadDeveloper.lastName": {
              "query": "Cam"
            }
          }
        }
      ],
      "filter": [
        {
          "range": {
            "startedOn": {
              "lt": "2018-01-01T00:00:00",
              "gte": "2017-01-01T00:00:00"
            }
          }
        }
      ]
    }
  }
}

一份文檔必須滿足三個查詢才算匹配成功

  1. 對名字和姓氏的 match 查詢有助於計算出相關性分數,因為它們都在查詢上下文中執行
  2. 針對開始日期的 range 查詢是在篩選上下文中執行的,索引沒有為匹配的文檔計算分數(針對這個查詢的所有文檔具有相同的分數 1.0

由於 bool 查詢非常常見,因此 NEST 在查詢上重載了運算符,以使得 bool 查詢的形式更加簡潔。前面的 bool 查詢可以更加簡潔地表示為

searchResponse = client.Search<Project>(s => s
    .Query(q => q
        .Match(m => m
            .Field(f => f.LeadDeveloper.FirstName)
            .Query("Russ")
        ) && q 
        .Match(m => m
            .Field(f => f.LeadDeveloper.LastName)
            .Query("Cam")
        ) && +q 
        .DateRange(r => r
            .Field(f => f.StartedOn)
            .GreaterThanOrEquals(new DateTime(2017, 01, 01))
            .LessThan(new DateTime(2018, 01, 01))
        )
    )
);

查看 writing bool queries ,瞭解有關 bool 查詢的更多詳細信息和示例

Search response

搜索查詢返回的響應是一個 ISearchResponse<T> 對象,其中 T 是在調用搜索方法時傳入的泛型參數類型。響應對象有幾個屬性,其中你最可能使用的是 .Documents ,我們將在下麵演示。

Matching documents

獲取匹配搜索查詢的文檔是相當簡單的

var searchResponse = client.Search<Project>(s => s
    .Query(q => q
        .MatchAll()
    )
);

var projects = searchResponse.Documents;

.Documents 是對下麵這段邏輯的一個方便的速記

searchResponse.HitsMetaData.Hits.Select(h => h.Source);

並且可以從命中集合中檢索有關每個命中的其他元數據。下麵的示例在使用 highlighting 時檢索命中的突出顯示

var highlights = searchResponse.HitsMetaData.Hits.Select(h => h
    .Highlights 
);

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 對OSGI的簡單理解 就像Java Web應用程式需要運行在Tomcat、Weblogic這樣的容器中一樣。程式員開發的OSGI程式包也需要運行在OSGI容器中。目前主流的OSGI容器包括:Apache Felix以及Eclipse Equinox。OSGI程式包在OSGI中稱作Bundle。 Bu ...
  • byte short char都是隱性int類型都可以,以及他們的包裝類 long 不行 String也可以,要求case中也為String類型 ...
  • &與&&都是邏輯與 不同的是&左右兩邊的判斷都要進行,而&&是短路與,當&&左邊條件為假則不用再判斷右邊條件,所以效率更高 例如,對於if(str != null && !str.equals(“”))表達式,當str為null時,後面的表達式不會執行,所以不會出現NullPointerExcept ...
  • 一個RabbitMQ消息代理是一個由一個或多個Erlang節點組成的邏輯組,其中的每個節點都共用users, virtual hosts, queues, exchanges, bindings, and runtime parameters。我們把這些相關節點組成的集合作為一個cluster(集群 ...
  • Python版本:3.5.2 日期:2018/1/21 ~~~~ __Author__ = "Lance " coding = utf 8 from urllib import request from urllib import parse from http import cookiejar f ...
  • 1.創建Maven項目 1.1File->New->Project 1.2填寫GroupId和ArtifactId 1.3直接Finish,然後等一會,等Maven載入完 完成以後的項目結構 2.配置Project Structure 2.1點擊如圖所示按鈕 2.2Project項按照預設配置 2. ...
  • 近期在學習DotNetty,遇到不少的問題。由於dotnetty是次netty的.net版本的實現。導致在網上敘述dotnetty的原理,以及實現技巧方面的東西較少,這還是十分惱人的。在此建議學習和使用Dotnetty的和位小伙伴,真心閱讀下netty的相關書籍,如《netty權威指南》。 閑話少說 ...
  • 最新下載地址:https://pan.baidu.com/s/1gg4zxaN, 具體參看官網MultiColorWin或者百度 搜索 關於這個軟體,後面只是功能修改,沒有必要再發表博客了 本軟體主要讓用戶能夠自定義文件夾和磁盤的樣式,直接上幾張圖 01、安裝界面 02 、軟體截圖 1、在個性化文件 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...