🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] > [github](https://github.com/blevesearch/bleve) ## 概述 * 索引任何 Go 数据结构(包括 JSON) * 强大的配置支持智能默认设置 * 支持的字段类型: * `text`,,,,,,,,`number`​`datetime`​`boolean`​`geopoint`​`geoshape`​`IP`​`vector` * 支持的查询类型: * 术语、短语、匹配、匹配短语、前缀、模糊 * 连词、析取、布尔 (`must`/`should`/`must_not`) * 术语范围、数字范围、日期范围 * [地理空间](https://github.com/blevesearch/bleve/blob/master/geo/README.md) * 简单[查询字符串语法](http://www.blevesearch.com/docs/Query-String-Query/) * [向量搜索](https://github.com/blevesearch/bleve/blob/master/docs/vectors.md) * [tf-idf](https://en.wikipedia.org/wiki/Tf-idf)评分 * 查询时间提升 * 使用文档片段突出显示搜索结果匹配项 * 聚合/方面支持: * 条款方面 * 数字范围方面 * 日期范围方面 ## 语法 ## 示例 ### 索引存储方式 已文件形式存放索引 ``` mapping := bleve.NewIndexMapping() index, err := bleve.New("example.bleve", mapping) if err != nil { panic(err) } ``` 纯内存索引 ``` indexMapping := bleve.NewIndexMapping() index, err := bleve.NewMemOnly(indexMapping) ``` ### 创建索引 ``` func CreateOrLoadIndex() (bleve.Index, error) { open, err := bleve.Open("example.bleve") if err != nil { if err != bleve.ErrorIndexPathDoesNotExist { return nil, err } open, err = bleve.New("example.bleve", bleve.NewIndexMapping()) if err != nil { return nil, err } } return open, nil } ``` ### 添加索引 #### 单个 ``` //WriteIndex 写入单条索引,如果索引已经存在则删除重建 func WriteIndex(index bleve.Index) error { for i := 0; i < 10; i++ { idStr := strconv.Itoa(i) _ = index.Delete(idStr) if err := index.Index(idStr, Meta{ Id: i, Body: "test bodyindex" + idStr, From: "test bodyindex" + idStr, }); err != nil { return err } } return nil } ``` #### 批量写入索引(推荐) ``` //WriteBatchIndex 批量写入索引数据 func WriteBatchIndex(index bleve.Index) error { batchDel := index.NewBatch() batchAdd := index.NewBatch() for i := 0; i < 10; i++ { idStr := strconv.Itoa(i) batchDel.Delete(idStr) if err := batchAdd.Index(idStr, Meta{ Id: i, Body: "test bodyindex" + idStr, From: "test bodyindex" + idStr, }); err != nil { return err } } _ = index.Batch(batchDel) return index.Batch(batchAdd) } ``` ### 搜索指指定索引 ``` func ReadFieldIndex(index bleve.Index) (*bleve.SearchResult, error) { query := bleve.NewMatchQuery("body") query.SetField("from") request := bleve.NewSearchRequest(query) search, err := index.Search(request) if err != nil { return nil, err } return search, nil } ``` ### 翻页 ``` query := bleve.NewMatchQuery("test") page := 1 pageSize := 2 from := (page - 1) * pageSize searchRequest := bleve.NewSearchRequestOptions(query, pageSize, from, false) ``` ### 语法高亮 ``` func main() { // 创建或打开一个新的索引 indexMapping := bleve.NewIndexMapping() index, err := bleve.NewMemOnly(indexMapping) if err != nil { log.Fatal(err) } // 创建一些示例文档 docs := []struct { ID string Title string Body string }{ {ID: "1", Title: "Hello World", Body: `1.右键群组设置接收消息不 World`}, {ID: "2", Title: "Go Programming", Body: "Go is an open-source programming language search World"}, {ID: "3", Title: "Bleve search", Body: " is a full-text and indexing library written in Go."}, } // 索引这些文档 for _, doc := range docs { err = index.Index(doc.ID, doc) if err != nil { log.Fatal(err) } } request := bleve.NewSearchRequest(bleve.NewMatchQuery("World")) request.Highlight = bleve.NewHighlight() searchResults, err := index.Search(request) if err != nil { log.Fatal(err) } // 打印搜索结果 fmt.Println("Search Results:") for _, hit := range searchResults.Hits { fmt.Printf("%#v\n", hit.Fragments) fmt.Printf("Document ID: %s, Score: %f\n", hit.ID, hit.Score) //search.FieldFragmentMap{"Body":[]string{"1.右键群组设置接收消息不 <mark>World</mark> "}, "Title":[]string{"Hello <mark>World</mark>"}} //Document ID: 1, Score: 0.496907 } // 当关键词在 body 和title 被同时匹配时,会同时输出 //output: //search.FieldFragmentMap{"Body":[]string{"1.右键群组设置接收消息不 <mark>World</mark>"}, "Title":[]string{"Hello <mark>World</mark>"}} //Document ID: 1, Score: 0.353553 //search.FieldFragmentMap{"Body":[]string{"Go is an open-source programming language search <mark>World</mark>"}} //Document ID: 2, Score: 0.316228 } ```