下一个richscms的版本,将可以选择是否使用meilisearch来实现文章的全文检索,让你的网站拥有高效的站内搜索功能。
一、meilisearch 是什么?
meilisearch是一个开源的,使用rust开发的轻量级全搜索引擎,很方便部署和对接API。
项目官网: https://www.meilisearch.com/
二、在richsm中使用meilisearch的sdk:
package search
import (
"encoding/json"
"fmt"
"github.com/meilisearch/meilisearch-go"
"github.com/zituocn/richcms/common/repository/view"
)
// MeiliSearch 使用 MeiliSearch的go sdk
type MeiliSearch struct {
addr string
key string
indexName string
client meilisearch.ServiceManager
}
// NewMeiliSearch 返回一个新的 搜索
func NewMeiliSearch(addr, key, indexName string) (ms *MeiliSearch, err error) {
if addr == "" || key == "" || indexName == "" {
return nil, fmt.Errorf("缺少配置参数")
}
ms = &MeiliSearch{
addr: addr,
key: key,
indexName: indexName,
client: meilisearch.New(addr, meilisearch.WithAPIKey(key)),
}
return
}
// Search 搜索
//
// offset ,limit
// 返回结构体与总条数
func (m *MeiliSearch) Search(offset, limit int64, s string) (data []*view.ArticleSearch, count int64, err error) {
index := m.client.Index(m.indexName)
result, err1 := index.Search(s,
&meilisearch.SearchRequest{
Offset: offset,
Limit: limit,
AttributesToHighlight: []string{"*"},
})
if err1 != nil {
err = err1
return
}
b, err2 := json.Marshal(result.Hits)
if err2 != nil {
err = err2
return
}
err = json.Unmarshal(b, &data)
if err != nil {
return
}
count = result.EstimatedTotalHits
return
}
// AddDocuments 添加一条或多条到索引
func (m *MeiliSearch) AddDocuments(data []*view.ArticleSearch) error {
if len(data) == 0 {
return fmt.Errorf("没有待索引的数据")
}
index := m.client.Index(m.indexName)
documents := make([]map[string]interface{}, len(data))
for _, v := range data {
documents = append(documents, map[string]interface{}{
"id": v.Id,
"title": v.Title,
"cate_id": v.CateId,
"cate_name": v.CateName,
"photo": v.Photo,
"author": v.Author,
"description": v.Description,
"month": v.Month,
"views": v.Views,
"is_hot": v.IsHot,
"updated": v.Updated,
"created": v.Created,
})
}
_, err := index.AddDocuments(documents)
if err != nil {
return err
}
return nil
}
// DeleteDocument 根据主键删除文档
func (m *MeiliSearch) DeleteDocument(id int64) error {
index := m.client.Index(m.indexName)
_, err := index.DeleteDocument(fmt.Sprintf("%d", id))
if err != nil {
return err
}
return nil
}
// UpdateDocument 更新
func (m *MeiliSearch) UpdateDocument(v *view.ArticleSearch) error {
if v == nil || v.Id == 0 {
return fmt.Errorf("没有待索引的数据")
}
index := m.client.Index(m.indexName)
document := map[string]interface{}{
"id": v.Id,
"title": v.Title,
"cate_id": v.CateId,
"cate_name": v.CateName,
"photo": v.Photo,
"author": v.Author,
"description": v.Description,
"month": v.Month,
"views": v.Views,
"is_hot": v.IsHot,
"updated": v.Updated,
"created": v.Created,
}
_, err := index.UpdateDocuments(document)
if err != nil {
return err
}
return nil
}
// Health 健康检测
func (m *MeiliSearch) Health() (*meilisearch.Health, error) {
return m.client.Health()
}
以上代码是基于github.com/meilisearch/meilisearch-go的封装。