bleve 一个性能很高的庫 ,从内存转到磁盘竟提升了近百倍有余

2,182 阅读2分钟

govleve

原本我司的一个项目用来做代码检索,之前用内存实现的正则匹配。 由于其搜索经常要达到数秒,甚至数十秒,后来尝试用了 blevesearch/bleve 这个go语言组件库,检索速度提升至单位毫秒级。

故在这里推荐大家可以去尝试学习使用

bleve介绍

blevesearch/bleve 是一个实现了高性能磁盘检索的go语言组件库

  • 索引任何go数据结构
  • 强大的配置支持
  • 支持的字段类型:
    • 文本、数字、日期
  • 支持的查询类型:
    • 术语、短语、匹配、匹配短语、前缀
    • 合取、析取、布尔
    • 数值范围、日期范围
    • 地理空间
    • 人工输入的简单查询语法
  • tf-idf 评分
  • 搜索结果匹配突出显示
  • 支持聚合方面:
    • 术语方面
    • 数值范围分面
    • 日期范围方面

创建或者加载索引

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 ReadIndex(index bleve.Index) (*bleve.SearchResult, error) {
   search, err := index.Search(bleve.NewSearchRequest(bleve.NewQueryStringQuery("bodyindex1")))
   if err != nil {
      return nil, err
   }
   return search, nil
}

高亮检索短语索引数据

将结果高亮打印出来

func ReadHighlightIndex(index bleve.Index) (*bleve.SearchResult, error) {
   query := bleve.NewPhraseQuery([]string{"test", "bodyindex1"}, "body")
   request := bleve.NewSearchRequest(query)
   request.Highlight = bleve.NewHighlight()
   search, err := index.Search(request)
   if err != nil {
      return nil, err
   }
   return search, nil
}

搜索指定字段

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
}

用例代码仓库地址 :gobleve