Skip to content

Commit

Permalink
Merge branch 'sea-team:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ncwsky authored Oct 29, 2022
2 parents 18ed004 + 2b8b816 commit d77c054
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 66 deletions.
78 changes: 48 additions & 30 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@

如果指定的数据库名没有存在,将会自动创建一个新的数据库。如果需要删除,直接删除改数据库目录,然后重启gofound即可。


## 增加/修改索引

需要在query参数中指定数据库名`database=default`

| 接口地址 | /api/index |
|------|------------------|
| 请求方式 | POST |
Expand All @@ -28,6 +29,12 @@
| text | string || 需要索引的文本块 |
| document | object || 附带的文档数据,json格式,搜索的时候原样返回 |

query参数(params-data)

| 字段 | 类型 | 必选 | 描述 |
|----------|--------|-----|--------|
| database | string || 指定数据库名 |

+ POST /api/index

```json
Expand All @@ -44,7 +51,7 @@
+ 命令行

```bash
curl -H "Content-Type:application/json" -X POST --data '{"id":88888,"text":"深圳北站","document":{"title":"阿森松岛所445","number":223}}' http://127.0.0.1:5678/api/index
curl -H "Content-Type:application/json" -X POST --data '{"id":88888,"text":"深圳北站","document":{"title":"阿森松岛所445","number":223}}' http://127.0.0.1:5678/api/index?database=default
```

### 响应
Expand All @@ -57,38 +64,41 @@ curl -H "Content-Type:application/json" -X POST --data '{"id":88888,"text":"深
```

## 批量增加/修改索引
与添加单个索引一样,也需要在query参数中指定数据库名`database=default`


| 接口地址 | /api/index/batch |
| 接口地址 | /api/index/batch |
|------|------------------|
| 请求方式 | POST |
| 请求类型 | application/json |

参数与单个一致,只是需要用数组包裹多个json对象,例如:

```json
[{
"id": 88888,
"text": "深圳北站",
"document": {
"title": "阿森松岛所445",
"number": 223
}
},{
"id": 22222,
"text": "北京东站",
"document": {
"title": "123123123",
"number": 123123
[
{
"id": 88888,
"text": "深圳北站",
"document": {
"title": "阿森松岛所445",
"number": 223
}
},
{
"id": 22222,
"text": "北京东站",
"document": {
"title": "123123123",
"number": 123123
}
}
}]
]
```


## 删除索引
与以上接口一样,也需要在query参数中指定数据库名`database=default`

| 接口地址 | /api/index/remove |
| -------- | ----------------- |
|------|-------------------|
| 请求方式 | POST |
| 请求类型 | application/json |

Expand All @@ -109,7 +119,7 @@ curl -H "Content-Type:application/json" -X POST --data '{"id":88888,"text":"深
+ 命令行

```bash
curl -H "Content-Type:application/json" -X POST --data '{"id":88888}' http://127.0.0.1:5678/api/remove
curl -H "Content-Type:application/json" -X POST --data '{"id":88888}' http://127.0.0.1:5678/api/remove?database=default
```

### 响应
Expand All @@ -132,15 +142,23 @@ curl -H "Content-Type:application/json" -X POST --data '{"id":88888}' http://127

### 请求

| 字段 | 类型 | 必选 | 描述 |
| --------- | ------ | ---- | ------------------------------------------------------------ |
| query | string || 查询的关键词,都是or匹配 |
| page | int || 页码,默认为1 |
| limit | int || 返回的文档数量,默认为100,没有最大限制,最好不要超过1000,超过之后速度会比较慢,内存占用会比较多 |
| order | string || 排序方式,取值`asc``desc`,默认为`desc`,按id排序,然后根据结果得分排序 |
| highlight | object || 关键字高亮,相对text字段中的文本 |
| 字段 | 类型 | 必选 | 描述 |
|-----------|--------|-----|----------------------------------------------------------------------------------------------|
| query | string || 查询的关键词,都是or匹配 |
| page | int || 页码,默认为1 |
| limit | int || 返回的文档数量,默认为100,没有最大限制,最好不要超过1000,超过之后速度会比较慢,内存占用会比较多 |
| order | string || 排序方式,取值`asc``desc`,默认为`desc`,按id排序,然后根据结果得分排序 |
| highlight | object || 关键字高亮,相对text字段中的文本 |
| scoreExp | string || 根据文档的字段计算分数,然后再进行排序,例如:score+[document.hot]*10,表达式中score为关键字的分数,document.hot为document中的hot字段 |


query参数(params-data)

| 字段 | 类型 | 必选 | 描述 |
|----------|--------|-----|---------------------|
| database | string || 指定数据库名,不填默认为default |


### highlight

> 配置以后,符合条件的关键词将会被preTag和postTag包裹
Expand Down Expand Up @@ -352,7 +370,7 @@ curl http://127.0.0.1:5678/api/status
## 删除数据库

| 接口地址 | /api/db/drop |
| -------- | ------------ |
|------|--------------|
| 请求方式 | GET |

### 请求
Expand All @@ -366,7 +384,7 @@ curl http://127.0.0.1:5678/api/drop?database=db_name
```json
{
"state": true,
"message": "success",
"message": "success"
}
```

Expand Down
77 changes: 41 additions & 36 deletions searcher/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ type Engine struct {
Tokenizer *words.Tokenizer //分词器
DatabaseName string //数据库名

Shard int //分片数
Timeout int64 //超时时间,单位秒
Shard int //分片数
Timeout int64 //超时时间,单位秒
BufferNum int //分片缓冲数

documentCount int64 //文档总数量
Expand Down Expand Up @@ -195,24 +195,19 @@ func (e *Engine) AddDocument(index *model.IndexDoc) {

splitWords := e.Tokenizer.Cut(text)

//id对应的词

//判断ID是否存在,如果存在,需要计算两次的差值,然后更新
id := index.Id
isUpdate := e.optimizeIndex(id, splitWords)

//没有更新
if !isUpdate {
return
}
// 检查是否需要更新倒排索引 words变更/id不存在
inserts, needUpdateInverted := e.optimizeIndex(id, splitWords)

for _, word := range splitWords {
e.addInvertedIndex(word, id)
// 将新增的word剔出单独处理,减少I/O操作
if needUpdateInverted {
for _, word := range inserts {
e.addInvertedIndex(word, id)
}
}

//添加id索引
// TODO: 是否需要更新正排索引 - 检测document变更
e.addPositiveIndex(index, splitWords)

}

// 添加倒排索引
Expand Down Expand Up @@ -242,24 +237,23 @@ func (e *Engine) addInvertedIndex(word string, id uint32) {
s.Set(key, utils.Encoder(ids))
}

// 移除没有的词
func (e *Engine) optimizeIndex(id uint32, newWords []string) bool {
//判断id是否存在
// 移除删去的词
func (e *Engine) optimizeIndex(id uint32, newWords []string) ([]string, bool) {
// 判断id是否存在
e.Lock()
defer e.Unlock()

//计算差值
removes, found := e.getDifference(id, newWords)
if found && len(removes) > 0 {
//从这些词中移除当前ID
for _, word := range removes {
e.removeIdInWordIndex(id, word)
// 计算差值
removes, inserts, changed := e.getDifference(id, newWords)
if changed {
if removes != nil && len(removes) > 0 {
// 移除正排索引
for _, word := range removes {
e.removeIdInWordIndex(id, word)
}
}
}

// 有没有更新
return !found || len(removes) > 0

return inserts, changed
}

func (e *Engine) removeIdInWordIndex(id uint32, word string) {
Expand Down Expand Up @@ -294,8 +288,9 @@ func (e *Engine) removeIdInWordIndex(id uint32, word string) {
}

// 计算差值
func (e *Engine) getDifference(id uint32, newWords []string) ([]string, bool) {

// @return []string: 需要删除的词
// @return bool : words出现变更返回true,否则返回false
func (e *Engine) getDifference(id uint32, newWords []string) ([]string, []string, bool) {
shard := e.getShard(id)
wordStorage := e.positiveIndexStorages[shard]
key := utils.Uint32ToBytes(id)
Expand All @@ -304,19 +299,29 @@ func (e *Engine) getDifference(id uint32, newWords []string) ([]string, bool) {
oldWords := make([]string, 0)
utils.Decoder(buf, &oldWords)

//计算需要移除的
// 计算需要移除的
removes := make([]string, 0)
for _, word := range oldWords {

//旧的在新的里面不存在,就是需要移除的
// 旧的在新的里面不存在,就是需要移除的
if !arrays.ArrayStringExists(newWords, word) {
removes = append(removes, word)
}
}
return removes, true
// 计算需要新增的
inserts := make([]string, 0)
for _, word := range newWords {
if !arrays.ArrayStringExists(oldWords, word) {
inserts = append(inserts, word)
}
}
if len(removes) != 0 || len(inserts) != 0 {
return removes, inserts, true
}
// 没有改变
return removes, inserts, false
}

return nil, false
// id不存在,相当于insert
return nil, newWords, true
}

// 添加正排索引 id=>keys id=>doc
Expand Down

0 comments on commit d77c054

Please sign in to comment.