全文檢索庫 bluge

wentao發表於2021-12-20

全文檢索庫 bluge

推薦理由

提到全文檢索庫,第一個想到的就是 Java 實現的 lucene,今天介紹一款 Golang 實現的全文檢索庫 bluge。bluge 脫胎於 Bleve,是當前 Github 比較火的搜尋引擎專案 zinc 的底層索引檢索庫。

功能介紹

bluge 索引儲存支援記憶體,本地檔案,以及擴充套件雲端儲存等方式,文件欄位型別支援 Text, Numeric, Date, Geo Point 等。

查詢檢索支援如下特性:

  1. 支援多種查詢方式:term/phrase/match 等基本的全文檢索,數字/時間範圍查詢;
  2. 聚合函式:Min/Max/Count/Sum/Avg/Weighted Avg;
  3. 匹配高亮。

使用指南

安裝

go get github.com/blugelabs/bluge

程式碼示例

下面是一個簡單的例子:

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/blugelabs/bluge"
)

func main() {
    // write index
    writeIndex("./data/bluge/")
    // batch insert
    batch("./data/bluge/")
    // search
    search("./data/bluge/")
}

// 建立索引
func writeIndex(indexPath string) {
    config := bluge.DefaultConfig(indexPath)
    writer, err := bluge.OpenWriter(config)
    if err != nil {
        log.Fatalf("error opening writer: %v", err)
    }
    defer writer.Close()

    // 新建文件
    doc := bluge.NewDocument("example").
        AddField(bluge.NewTextField("name", "bluge")).AddField(bluge.NewDateTimeField("created_at", time.Now()))

    err = writer.Update(doc.ID(), doc)
    if err != nil {
        log.Fatalf("error updating document: %v", err)
    }
}

// 批量建立
func batch(indexPath string) {
    writer, err := bluge.OpenWriter(bluge.DefaultConfig(indexPath))
    batch := bluge.NewBatch()
    for i := 0; i < 10; i++ {
        doc := bluge.NewDocument(fmt.Sprintf("example_%d", i)).
            AddField(bluge.NewTextField(fmt.Sprintf("field_%d", i), fmt.Sprintf("value_%d", i%2))).AddField(bluge.NewDateTimeField("created_at", time.Now()))
        batch.Insert(doc)
    }
    err = writer.Batch(batch)
    if err != nil {
        log.Fatalf("error executing batch: %v", err)
    }
    batch.Reset()
}

// 查詢
func search(indexPath string) {
    config := bluge.DefaultConfig(indexPath)
    reader, err := bluge.OpenReader(config)

    if err != nil {
        log.Fatalf("error getting index reader: %v", err)
    }
    defer reader.Close()

    query := bluge.NewMatchQuery("value_1").SetField("field_1")
    request := bluge.NewTopNSearch(10, query).
        WithStandardAggregations()
    documentMatchIterator, err := reader.Search(context.Background(), request)
    if err != nil {
        log.Fatalf("error executing search: %v", err)
    }
    match, err := documentMatchIterator.Next()
    for err == nil && match != nil {
        err = match.VisitStoredFields(func(field string, value []byte) bool {
            fmt.Printf("match: %s:%s\n", field, string(value))
            return true
        })
        if err != nil {
            log.Fatalf("error loading stored fields: %v", err)
        }
        fmt.Println(match)
        match, err = documentMatchIterator.Next()
    }
    if err != nil {
        log.Fatalf("error iterator document matches: %v", err)
    }
}

總結

bulge 是 Golang 實現的全文檢索庫,功能上類似 lucene,效能上相比 lucene 還有些差距,如果對全文檢索感興趣可以把玩把玩。

參考資料

  1. https://github.com/blugelabs/bluge
  2. https://blugelabs.com/bluge/
更多原創文章乾貨分享,請關注公眾號
  • 全文檢索庫 bluge
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章