5

bleve 索引库使用 示例

 8 months ago
source link: https://studygolang.com/articles/36305
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

bleve 索引库使用 示例

psp0811 · 2天之前 · 478 次点击 · 预计阅读时间 7 分钟 · 大约8小时之前 开始浏览    

bleve 索引库使用 示例

地址: github.com/blevesearch/bleve 版本 2.3.9

废话不多说,直接上代码

定义一个 client 客户端

package search
import (  
    "book/config/logger"  
    "fmt"  
    "github.com/blevesearch/bleve/v2"  
    "github.com/blevesearch/bleve/v2/mapping"  
)

// 封装的查询客户端  
type BevelSearchClient struct {  
    IndexName string  
    DocType string  
    Analyzer string  
    index bleve.Index  
    indexMapping *mapping.IndexMappingImpl  
    documentMapping *mapping.DocumentMapping  
}  
// 搜索字段结构体  
type BevelSearchFiled struct {  
    FiledName, FiledValue string  
}  

func (client *BevelSearchClient) CreateIndex() {  
    // 创建索引  
    tempIndex, err := bleve.New(client.IndexName, client.indexMapping)  
    if err != nil {  
        if err == bleve.ErrorIndexPathExists {  
            tempIndex, err = bleve.Open(client.IndexName)  
        } else {  
            panic(err)
        }  
    }  

    client.index = tempIndex  
    logger.Logger.Infoln(fmt.Sprintf("create index: %s success......",
    client.IndexName))  
}  

// CreateIndexMapping 创建索引并将字段映射添加到索引  
func (client *BevelSearchClient) CreateIndexMapping() *BevelSearchClient {  
    client.indexMapping = bleve.NewIndexMapping()  
    // 重要,索引也要设置分词器,否则不生效  
    client.indexMapping.DefaultAnalyzer = client.Analyzer  
    //client.indexMapping.DefaultType  
    // 将字段映射添加到索引映射中  
    client.indexMapping.AddDocumentMapping(client.DocType, client.documentMapping)  

    return client  
}  

// CreateDocMapping 定义字段映射  
func (client *BevelSearchClient) CreateDocMapping(docMapping *mapping.DocumentMapping) *BevelSearchClient {  
    client.documentMapping = docMapping  
    return client  
}  

// AddDoc 添加文档  
func (client *BevelSearchClient) AddDoc(id string, data any) {  
    err := client.index.Index(id, data)  
    if err != nil {  
        logger.Logger.Errorln("创建文档失败,失败原因:", err)  
    }  
}  

// GetIndex 仅查询时使用  
func (client *BevelSearchClient) GetIndex() *BevelSearchClient {  
    tempIndex, err := bleve.Open(client.IndexName)  
    if err != nil {  
        panic(err)  
    }  
    client.index = tempIndex  
    return client  
}  

func (client *BevelSearchClient) BuildSearchFiled(fields []BevelSearchFiled) *bleve.SearchRequest {  
    buildQuery := bleve.NewBooleanQuery()  

    for _, field := range fields {  
        termQuery := bleve.NewTermQuery(field.FiledValue) // 精确匹配字段值  
        termQuery.SetField(field.FiledName)  

        buildQuery.AddMust(termQuery)  
    }  
    searchRequest := bleve.NewSearchRequest(buildQuery)  
    //searchRequest := bleve.NewSearchRequestOptions(query, 10, 0, false) // 分页查询  
    return searchRequest  
}  

func (client *BevelSearchClient) search(request *bleve.SearchRequest) *bleve.SearchResult {  
    request.Fields = []string{"*"}  
    searchResults, err := client.index.Search(request)  
    if err != nil {  
        logger.Logger.Errorln("Error searching:", err)  
    }  
    client.index.Close()  

    return searchResults  
}  

func (client *BevelSearchClient) FindOne(request *bleve.SearchRequest) map[string]interface{} {  
    hits := client.search(request)  
    b := hits.Total > 0  

    if b {  
        match := hits.Hits[0]  
        return match.Fields  
    }  
    return nil  
}  

func (client *BevelSearchClient) FindList(request *bleve.SearchRequest) []map[string]interface{} {  
    hits := client.search(request)  
    b := hits.Total > 0  
    if b {  
        var res []map[string]interface{}  
        for _, hit := range hits.Hits {  
            res = append(res, hit.Fields)  
        }  
        return res  
    }  
    return nil  
}  

func (client *BevelSearchClient) DocCount() int64 {  
    // 执行查询,获取结果总数  
    count, err := client.index.DocCount()  
    if err != nil {  
        panic(err)  
    }  
    c := int64(count)  
    return c  
}  

func (client *BevelSearchClient) Close() {  
    defer client.index.Close()  
}

使用-创建索引&往文档里面写入数据

searchClient := search.BevelSearchClient{  
    IndexName: "pep-book",  
    DocType: "bookItem",  
    Analyzer: "simple", // 一定要引入 _ "github.com/blevesearch/bleve/v2/analysis/analyzer/simple"  
}
// 定义索引的文档 的mapping, 字段名与结构体的字段做映射
newTextFieldMapping := bleve.NewTextFieldMapping()  
// NewKeywordFieldMapping 使用关键字分析器返回文本的字段映射,该分析器基本上不应用任何特定的文本分析。  
newTextFieldMapping.Analyzer = searchClient.Analyzer // 默认是 standard 分词器
bookDockMapping.AddFieldMappingsAt("id", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("title", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("xd", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("xk", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("nj", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("cc", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("detail_config_js", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("local_config_js_path", newTextFieldMapping)  
bookDockMapping.AddFieldMappingsAt("iterm_image_total", bleve.NewNumericFieldMapping())  

// 将数组|切片类型的字段  当做子文档来类型来存储到 book 主文档里面  
arrayMapping := bleve.NewDocumentMapping()  
arrayMapping.AddFieldMappingsAt("image_url", bleve.NewTextFieldMapping())  
arrayMapping.AddFieldMappingsAt("index", bleve.NewNumericFieldMapping()) // If you want to query by index  
arrayMapping.AddFieldMappingsAt("local_image_path", bleve.NewTextFieldMapping()) 
bookDockMapping.AddSubDocumentMapping("iterm_image_list", arrayMapping)  
// 注意:子文档的字段访问方式是:iterm_image_list.image_url ,其他字段 以此类推


searchClient.CreateDocMapping(bookDockMapping).CreateIndexMapping().CreateIndex()

// 将数据写入索引中
for _, book := range *list {  
    searchClient.AddDoc(book.ID, book)  
}

使用-搜索文档

// 从索引中拿数据  
request := searchClient.BuildSearchFiled([]search.BevelSearchFiled{  
    {FiledName: "xd", FiledValue: stage},  
    {FiledName: "nj", FiledValue: grade},  
    {FiledName: "xk", FiledValue: subject},  
    {FiledName: "cc", FiledValue: cc},  
})  
one := searchClient.GetIndex().FindOne(request)

list := searchClient.GetIndex().FindList(request)
  1. 仅引入 github.com/blevesearch/bleve/v2 不行,还需要引入:github.com/blevesearch/bleve/v2/mapping
  2. 默认装载的分词器只有 standard keyword ,想使用simple 分词器,需要再创建mapping时,额外引入 _ "github.com/blevesearch/bleve/v2/analysis/analyzer/simple", 否则会提示 未注册分词器
  3. document 的 字段分词器 最好和 索引的 mapping 分词器 一致,以免遇到不可预测问题。

github: https://github.com/blevesearch/bleve/tree/v2.3.9

分词器效果实验地址: https://bleveanalysis.couchbase.com/analysis


有疑问加站长微信联系(非本文作者))

280

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK