如何使用Elasticsearch在.NET應用程序中實現全文搜索

目錄

爲什麼選擇Elastic search?

示例應用程序

如何寫文件

如何查詢文件

獲得什麼

資源資源


在這個簡單的教程中,我將提供一個簡單的演示來向Elasticsearch讀寫文檔,併爲C#應用程序添加全文本搜索功能。Elasticsearch是一個分佈式的開源搜索引擎,可以管理各種數據。瞭解將其集成到ASP.NET應用程序有多麼簡單!

爲什麼選擇Elastic search

Elasticsearch是一個分佈式的開源搜索引擎,可以管理各種數據。但是,爲什麼Elasticsearch是全文的最佳解決方案?

我從2009年開始研究全文搜索,當時我必須爲數據推薦系統實現搜索算法。這次經歷非常有教育意義,但從頭開始是一次大屠殺。我第一次獲得使用庫的機會,我嘗試了Apache Lucene來實現全文搜索。隨着應用程序架構變得複雜(即,多個服務器需要共享索引數據),Solr提供了可擴展的解決方案。它是一個基於開源API的搜索引擎(基於Lucene)。使用完這些庫之後,我使用了Elasticsearch,它現在是市場的領導者。它帶有本地免費版本,可在雲上使用。它可以從簡單的安裝擴展到巨大的環境。所以問題是:爲什麼不呢?

示例應用程序

我在生產以及我的開源headless cms, RawCMS上成功地進行了彈性搜索。爲了展示Elasticsearch的工作原理,我創建了一個示例應用程序,其中實現了兩個主要功能:

  • 創建索引並向其中添加數據
  • 使用全文查詢讀取數據

示例代碼在GitHub可用。要運行和測試它,只需下載,編譯和執行:

dotnet ElasticSearchTest.dll create -f divina_commedia.txt -h http://localhost:9300
> Index created in 30338ms with 14006 element.

dotnet ElasticSearchTest.dll search -i divinacommediatxt 
                                    -h http://localhost:9300 -q "dante AND virgi*"
> Searching for $dante AND virgi*
> "Dante, perché Virgilio se ne vada,
> "Dante, perché Virgilio se ne vada,

控制檯應用程序使用該ConsoleLineParser庫以人工方式解析輸入。因此,我只爲動詞屬性添加了兩個類,並在控制檯動詞和要運行的代碼之間添加了映射。

private static void Main(string[] args)
{
    object x = CommandLine.Parser.Default.ParseArguments<CreateOptions, SearchOptions>(args)
      .MapResult(
        (CreateOptions opts) => DoCreate(opts),
        (SearchOptions opts) => DoSearch(opts),
        errs => 1);
}

根據用戶輸入(搜索或創建)的動詞,啓動傳遞參數的相應過程。

如何寫文件

寫作部分很容易。實際上,對於Elasticsearch,有兩種選擇。使用低級框架,您可以獲得彈性API的包裝實現。這有助於避免手動綁定和組合JSON有效負載。但是,如果您想使用數據,NEST是一個不錯的選擇。NEST是高級框架,如果您是ORM的專家,那麼這也就不足爲奇了。

您只需要爲要保存的文檔創建類,並定義如何使用註釋保存屬性並調用save API

我認爲這不太複雜,聽起來更像是一個常規例程。這是類定義的代碼片段。在此示例中,我每個文檔僅使用一個包含一行文本的字段。

public class LogDocument
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string Body { get; set; }
}

下一步是創建索引。在這一步中,我們將索引與類相關聯。可以手動完成此操作,指定存儲設置或使用自動映射。在我們的示例中,Id字段會自動映射到文檔的唯一標識符。

client.Indices.Create(indexName, c => c
                .Map<LogDocument>(m => m
                    .AutoMap<LogDocument>()
                )
            );

最後,我們擁有代碼中最愚蠢的部分:寫入數據。因爲我們要將所有詩句保存到許多文檔中(每行一個),所以我們只是進行一次迭代。

string[] lines = File.ReadAllLines(filepath);

int items = 0;
Parallel.ForEach(lines, (line) =>
{
    if (!string.IsNullOrWhiteSpace(line))
    {
        client.CreateDocument<LogDocument>(new LogDocument()
        {
            Body = line.Trim()
        });
        items++;
    }
});

請注意,通過外部系統使用API​​,我們可以使用並行構造來提高性能。

如何查詢文件

這部分非常簡單而且非常清楚——至少我希望如此。訪問文檔的基本方法是使用常規流利的LINQ語法。這是基本用法,我更願意將這個演示集中在文檔不太完善的搜索全文數據用例上。

Elastic允許使用原始查詢來查找字段數據。爲此,您可以使用正確的Search方法重載,配置原始查詢:

var searchResponse = client.Search<LogDocument>(s => s
                        .Size(10)
                        .Query(q => q.QueryString(

                            qs => qs.Query(searchStr)
                            .AllowLeadingWildcard(true)
                            )
                        )
                    );

var docs = searchResponse.Documents;

獲得什麼

Elasticsearch是領先的搜索引擎解決方案。它爲應用程序提供了諸如全文搜索或文檔索引之類的豐富功能。它可以用作服務或內部部署。無論哪種情況,配置基本用法都非常簡單。

NEST框架使我們可以像通過LINQ進行簡單數據庫存儲和訪問Elasticsearch一樣,這使一切變得非常簡單。

對於要讓最終用戶編寫查詢的複雜情況,可以使用原始查詢並將結果映射到類。

資源資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章