在richcms中可以配置使用meilisearch,实现高效、快速的站内搜索,以下是richcms源码中封装的meilisearch调用代码。主要包括,新增、更新、删除和查询文档的操作。
源码文件:
common/sdk/search/meili_search.go
package search
import (
"encoding/json"
"fmt"
"github.com/meilisearch/meilisearch-go"
"github.com/zituocn/logx"
"github.com/zituocn/richcms/common/repository/model"
"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
}
// UpdateSortable 更新某个字体段为可排序的状态
func (m *MeiliSearch) UpdateSortable(ss []string) error {
if len(ss) > 0 {
_, err := m.client.Index(m.indexName).UpdateSortableAttributes(&ss)
return err
}
return nil
}
// Search 搜索
//
// offset ,limit
// 返回结构体与总条数
// 按updated排序
func (m *MeiliSearch) Search(offset, limit int64, s string) (data []*view.ArticleSearch, count int64, err error) {
sortableAttributes := []string{
"updated",
}
err = m.UpdateSortable(sortableAttributes)
if err != nil {
return
}
index := m.client.Index(m.indexName)
result, err1 := index.Search(s,
&meilisearch.SearchRequest{
Offset: offset,
Limit: limit,
AttributesToHighlight: []string{"*"},
Sort: []string{
"updated:desc",
}},
)
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 []*model.Article) error {
if len(data) == 0 {
return fmt.Errorf("没有待索引的数据")
}
index := m.client.Index(m.indexName)
documents := make([]map[string]interface{}, 0)
for _, v := range data {
documents = append(documents, map[string]interface{}{
"id": v.Id,
"author": v.Author,
"cid": v.CateId,
"title": v.Title,
"photo": v.Photo,
"updated": v.Updated,
"created": v.Created,
})
documents = append(documents)
}
_, err := index.AddDocuments(documents, "id")
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 *model.Article) error {
if v == nil || v.Id == 0 {
return fmt.Errorf("没有待索引的数据")
}
document := map[string]interface{}{
"id": v.Id,
"title": v.Title,
"cid": v.CateId,
"photo": v.Photo,
"author": v.Author,
"updated": v.Updated,
"created": v.Created,
}
task, err := m.client.Index(m.indexName).UpdateDocuments(document, "id")
if err != nil {
return err
}
logx.Infof("%#v", task)
return nil
}
// DeleteIndex 删除当前index
func (m *MeiliSearch) DeleteIndex() error {
_, err := m.client.DeleteIndex(m.indexName)
return err
}
// Health 健康检测
func (m *MeiliSearch) Health() (*meilisearch.Health, error) {
return m.client.Health()
}
// Version 版本检测
func (m *MeiliSearch) Version() (*meilisearch.Version, error) {
return m.client.Version()
}