Skip to content

Commit 477ef46

Browse files
authored
Add more tests and docs for issue indexer, add db indexer type for searching from database (#6144)
* add more tests and docs for issue indexer, add db indexer type for searching from database * fix typo * fix typo * fix lint * improve docs
1 parent 0751153 commit 477ef46

File tree

12 files changed

+174
-11
lines changed

12 files changed

+174
-11
lines changed

custom/conf/app.ini.sample

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,19 @@ DB_RETRIES = 10
253253
; Backoff time per DB retry (time.Duration)
254254
DB_RETRY_BACKOFF = 3s
255255

256-
257256
[indexer]
257+
; Issue indexer type, currently support: bleve or db, default is bleve
258+
ISSUE_INDEXER_TYPE = bleve
259+
; Issue indexer storage path, available when ISSUE_INDEXER_TYPE is bleve
258260
ISSUE_INDEXER_PATH = indexers/issues.bleve
261+
; Issue indexer queue, currently support: channel or levelqueue, default is levelqueue
262+
ISSUE_INDEXER_QUEUE_TYPE = levelqueue
263+
; When ISSUE_INDEXER_QUEUE_TYPE is levelqueue, this will be the queue will be saved path,
264+
; default is indexers/issues.queue
265+
ISSUE_INDEXER_QUEUE_DIR = indexers/issues.queue
266+
; Batch queue number, default is 20
267+
ISSUE_INDEXER_QUEUE_BATCH_NUMBER = 20
268+
259269
; repo indexer by default disabled, since it uses a lot of disk space
260270
REPO_INDEXER_ENABLED = false
261271
REPO_INDEXER_PATH = indexers/repos.bleve

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,12 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
154154

155155
## Indexer (`indexer`)
156156

157+
- `ISSUE_INDEXER_TYPE`: **bleve**: Issue indexer type, currently support: bleve or db, if it's db, below issue indexer item will be invalid.
157158
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search.
159+
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: Issue indexer queue, currently support: channel or levelqueue
160+
- `ISSUE_INDEXER_QUEUE_DIR`: **indexers/issues.queue**: When ISSUE_INDEXER_QUEUE_TYPE is levelqueue, this will be the queue will be saved path
161+
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: Batch queue number
162+
158163
- `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space).
159164
- `REPO_INDEXER_PATH`: **indexers/repos.bleve**: Index file used for code search.
160165
- `UPDATE_BUFFER_LEN`: **20**: Buffer length of index request.

docs/content/doc/advanced/config-cheat-sheet.zh-cn.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ menu:
8282
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
8383
- `LOG_SQL`: **true**: 显示生成的SQL,默认为真。
8484

85+
86+
## Indexer (`indexer`)
87+
88+
- `ISSUE_INDEXER_TYPE`: **bleve**: 工单索引类型,当前支持 `bleve``db`,当为 `db` 时其它工单索引项可不用设置。
89+
- `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: 工单索引文件存放路径,当索引类型为 `bleve` 时有效。
90+
- `ISSUE_INDEXER_QUEUE_TYPE`: **levelqueue**: 工单索引队列类型,当前支持 `channel``levelqueue`
91+
- `ISSUE_INDEXER_QUEUE_DIR`: **indexers/issues.queue**: 当 `ISSUE_INDEXER_QUEUE_TYPE``levelqueue` 时,保存索引队列的磁盘路径。
92+
- `ISSUE_INDEXER_QUEUE_BATCH_NUMBER`: **20**: 队列处理中批量提交数量。
93+
94+
- `REPO_INDEXER_ENABLED`: **false**: 是否启用代码搜索(启用后会占用比较大的磁盘空间)。
95+
- `REPO_INDEXER_PATH`: **indexers/repos.bleve**: 用于代码搜索的索引文件路径。
96+
- `UPDATE_BUFFER_LEN`: **20**: 代码索引请求的缓冲区长度。
97+
- `MAX_FILE_SIZE`: **1048576**: 进行解析的源代码文件的最大长度,小于该值时才会索引。
98+
8599
## Security (`security`)
86100

87101
- `INSTALL_LOCK`: 是否允许运行安装向导,(跟管理员账号有关,十分重要)。

models/issue.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,40 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen
16841684
return openResult, closedResult
16851685
}
16861686

1687+
// SearchIssueIDsByKeyword search issues on database
1688+
func SearchIssueIDsByKeyword(kw string, repoID int64, limit, start int) (int64, []int64, error) {
1689+
var repoCond = builder.Eq{"repo_id": repoID}
1690+
var subQuery = builder.Select("id").From("issue").Where(repoCond)
1691+
var cond = builder.And(
1692+
repoCond,
1693+
builder.Or(
1694+
builder.Like{"name", kw},
1695+
builder.Like{"content", kw},
1696+
builder.In("id", builder.Select("issue_id").
1697+
From("comment").
1698+
Where(builder.And(
1699+
builder.Eq{"type": CommentTypeComment},
1700+
builder.In("issue_id", subQuery),
1701+
builder.Like{"content", kw},
1702+
)),
1703+
),
1704+
),
1705+
)
1706+
1707+
var ids = make([]int64, 0, limit)
1708+
err := x.Distinct("id").Table("issue").Where(cond).Limit(limit, start).Find(&ids)
1709+
if err != nil {
1710+
return 0, nil, err
1711+
}
1712+
1713+
total, err := x.Distinct("id").Table("issue").Where(cond).Count()
1714+
if err != nil {
1715+
return 0, nil, err
1716+
}
1717+
1718+
return total, ids, nil
1719+
}
1720+
16871721
func updateIssue(e Engine, issue *Issue) error {
16881722
_, err := e.ID(issue.ID).AllCols().Update(issue)
16891723
if err != nil {

models/issue_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,28 @@ func TestIssue_loadTotalTimes(t *testing.T) {
295295
assert.NoError(t, ms.loadTotalTimes(x))
296296
assert.Equal(t, int64(3662), ms.TotalTrackedTime)
297297
}
298+
299+
func TestIssue_SearchIssueIDsByKeyword(t *testing.T) {
300+
assert.NoError(t, PrepareTestDatabase())
301+
302+
total, ids, err := SearchIssueIDsByKeyword("issue2", 1, 10, 0)
303+
assert.NoError(t, err)
304+
assert.EqualValues(t, 1, total)
305+
assert.EqualValues(t, []int64{2}, ids)
306+
307+
total, ids, err = SearchIssueIDsByKeyword("first", 1, 10, 0)
308+
assert.NoError(t, err)
309+
assert.EqualValues(t, 1, total)
310+
assert.EqualValues(t, []int64{1}, ids)
311+
312+
total, ids, err = SearchIssueIDsByKeyword("for", 1, 10, 0)
313+
assert.NoError(t, err)
314+
assert.EqualValues(t, 4, total)
315+
assert.EqualValues(t, []int64{1, 2, 3, 5}, ids)
316+
317+
// issue1's comment id 2
318+
total, ids, err = SearchIssueIDsByKeyword("good", 1, 10, 0)
319+
assert.NoError(t, err)
320+
assert.EqualValues(t, 1, total)
321+
assert.EqualValues(t, []int64{1}, ids)
322+
}

modules/indexer/issues/db.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package issues
6+
7+
import "code.gitea.io/gitea/models"
8+
9+
// DBIndexer implements Indexer inteface to use database's like search
10+
type DBIndexer struct {
11+
}
12+
13+
// Init dummy function
14+
func (db *DBIndexer) Init() (bool, error) {
15+
return false, nil
16+
}
17+
18+
// Index dummy function
19+
func (db *DBIndexer) Index(issue []*IndexerData) error {
20+
return nil
21+
}
22+
23+
// Delete dummy function
24+
func (db *DBIndexer) Delete(ids ...int64) error {
25+
return nil
26+
}
27+
28+
// Search dummy function
29+
func (db *DBIndexer) Search(kw string, repoID int64, limit, start int) (*SearchResult, error) {
30+
total, ids, err := models.SearchIssueIDsByKeyword(kw, repoID, limit, start)
31+
if err != nil {
32+
return nil, err
33+
}
34+
var result = SearchResult{
35+
Total: total,
36+
Hits: make([]Match, 0, limit),
37+
}
38+
for _, id := range ids {
39+
result.Hits = append(result.Hits, Match{
40+
ID: id,
41+
RepoID: repoID,
42+
})
43+
}
44+
return &result, nil
45+
}

modules/indexer/issues/indexer.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ type Match struct {
3333

3434
// SearchResult represents search results
3535
type SearchResult struct {
36-
Hits []Match
36+
Total int64
37+
Hits []Match
3738
}
3839

3940
// Indexer defines an inteface to indexer issues contents
@@ -54,6 +55,7 @@ var (
5455
// all issue index done.
5556
func InitIssueIndexer(syncReindex bool) error {
5657
var populate bool
58+
var dummyQueue bool
5759
switch setting.Indexer.IssueType {
5860
case "bleve":
5961
issueIndexer = NewBleveIndexer(setting.Indexer.IssuePath)
@@ -62,10 +64,17 @@ func InitIssueIndexer(syncReindex bool) error {
6264
return err
6365
}
6466
populate = !exist
67+
case "db":
68+
issueIndexer = &DBIndexer{}
69+
dummyQueue = true
6570
default:
6671
return fmt.Errorf("unknow issue indexer type: %s", setting.Indexer.IssueType)
6772
}
6873

74+
if dummyQueue {
75+
return nil
76+
}
77+
6978
var err error
7079
switch setting.Indexer.IssueIndexerQueueType {
7180
case setting.LevelQueueType:

modules/indexer/issues/indexer_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,8 @@ func TestSearchIssues(t *testing.T) {
4848
ids, err = SearchIssuesByKeyword(1, "for")
4949
assert.NoError(t, err)
5050
assert.EqualValues(t, []int64{1, 2, 3, 5}, ids)
51+
52+
ids, err = SearchIssuesByKeyword(1, "good")
53+
assert.NoError(t, err)
54+
assert.EqualValues(t, []int64{1}, ids)
5155
}

modules/indexer/issues/queue.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,19 @@ package issues
77
// Queue defines an interface to save an issue indexer queue
88
type Queue interface {
99
Run() error
10-
Push(*IndexerData)
10+
Push(*IndexerData) error
11+
}
12+
13+
// DummyQueue represents an empty queue
14+
type DummyQueue struct {
15+
}
16+
17+
// Run starts to run the queue
18+
func (b *DummyQueue) Run() error {
19+
return nil
20+
}
21+
22+
// Push pushes data to indexer
23+
func (b *DummyQueue) Push(*IndexerData) error {
24+
return nil
1125
}

modules/indexer/issues/queue_channel.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ func (c *ChannelQueue) Run() error {
3333
for {
3434
select {
3535
case data := <-c.queue:
36+
if data.IsDelete {
37+
c.indexer.Delete(data.IDs...)
38+
continue
39+
}
40+
3641
datas = append(datas, data)
3742
if len(datas) >= c.batchNumber {
3843
c.indexer.Index(datas)
@@ -51,6 +56,7 @@ func (c *ChannelQueue) Run() error {
5156
}
5257

5358
// Push will push the indexer data to queue
54-
func (c *ChannelQueue) Push(data *IndexerData) {
59+
func (c *ChannelQueue) Push(data *IndexerData) error {
5560
c.queue <- data
61+
return nil
5662
}

modules/indexer/issues/queue_disk.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,10 @@ func (l *LevelQueue) Run() error {
9494
}
9595

9696
// Push will push the indexer data to queue
97-
func (l *LevelQueue) Push(data *IndexerData) {
97+
func (l *LevelQueue) Push(data *IndexerData) error {
9898
bs, err := json.Marshal(data)
9999
if err != nil {
100-
log.Error(4, "Marshal: %v", err)
101-
return
102-
}
103-
err = l.queue.LPush(bs)
104-
if err != nil {
105-
log.Error(4, "LPush: %v", err)
100+
return err
106101
}
102+
return l.queue.LPush(bs)
107103
}

modules/setting/indexer.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var (
3838

3939
func newIndexerService() {
4040
sec := Cfg.Section("indexer")
41+
Indexer.IssueType = sec.Key("ISSUE_INDEXER_TYPE").MustString("bleve")
4142
Indexer.IssuePath = sec.Key("ISSUE_INDEXER_PATH").MustString(path.Join(AppDataPath, "indexers/issues.bleve"))
4243
if !filepath.IsAbs(Indexer.IssuePath) {
4344
Indexer.IssuePath = path.Join(AppWorkPath, Indexer.IssuePath)

0 commit comments

Comments
 (0)