@@ -6,6 +6,7 @@ package code
6
6
7
7
import (
8
8
"context"
9
+ "encoding/json"
9
10
"errors"
10
11
"fmt"
11
12
"strconv"
@@ -85,7 +86,7 @@ const (
85
86
"content": {
86
87
"type": "text",
87
88
"index": true
88
- },
89
+ }
89
90
}
90
91
}
91
92
}`
@@ -115,65 +116,73 @@ func (b *ElasticSearchIndexer) init() (bool, error) {
115
116
return true , nil
116
117
}
117
118
118
- func (b * ElasticSearchIndexer ) addUpdate (sha string , update fileUpdate , repo * models.Repository , reqs []elastic.BulkableRequest ) error {
119
+ func (b * ElasticSearchIndexer ) addUpdate (sha string , update fileUpdate , repo * models.Repository ) ( []elastic.BulkableRequest , error ) {
119
120
stdout , err := git .NewCommand ("cat-file" , "-s" , update .BlobSha ).
120
121
RunInDir (repo .RepoPath ())
121
122
if err != nil {
122
- return err
123
+ return nil , err
123
124
}
124
125
if size , err := strconv .Atoi (strings .TrimSpace (stdout )); err != nil {
125
- return fmt .Errorf ("Misformatted git cat-file output: %v" , err )
126
+ return nil , fmt .Errorf ("Misformatted git cat-file output: %v" , err )
126
127
} else if int64 (size ) > setting .Indexer .MaxIndexerFileSize {
127
- return b .addDelete (update .Filename , repo , reqs )
128
+ return b .addDelete (update .Filename , repo )
128
129
}
129
130
130
131
fileContents , err := git .NewCommand ("cat-file" , "blob" , update .BlobSha ).
131
132
RunInDirBytes (repo .RepoPath ())
132
133
if err != nil {
133
- return err
134
+ return nil , err
134
135
} else if ! base .IsTextFile (fileContents ) {
135
136
// FIXME: UTF-16 files will probably fail here
136
- return nil
137
+ return nil , nil
137
138
}
138
139
139
140
id := filenameIndexerID (repo .ID , update .Filename )
140
141
141
- reqs = append ( reqs , elastic .NewBulkIndexRequest ().
142
- Index ( b . indexerName ).
143
- Id ( id ).
144
- Doc ( map [ string ] interface {}{
145
- "repo_id" : repo . ID ,
146
- "content " : string ( charset . ToUTF8DropErrors ( fileContents )) ,
147
- "commit_id " : sha ,
148
- "language " : analyze . GetCodeLanguage ( update . Filename , fileContents ) ,
149
- "updated_at " : time . Now (). UTC ( ),
150
- }))
151
-
152
- return nil
142
+ return [] elastic.BulkableRequest {
143
+ elastic . NewBulkIndexRequest ( ).
144
+ Index ( b . indexerName ).
145
+ Id ( id ).
146
+ Doc ( map [ string ] interface {}{
147
+ "repo_id " : repo . ID ,
148
+ "content " : string ( charset . ToUTF8DropErrors ( fileContents )) ,
149
+ "commit_id " : sha ,
150
+ "language " : analyze . GetCodeLanguage ( update . Filename , fileContents ),
151
+ "updated_at" : time . Now (). UTC (),
152
+ }),
153
+ }, nil
153
154
}
154
155
155
- func (b * ElasticSearchIndexer ) addDelete (filename string , repo * models.Repository , reqs []elastic.BulkableRequest ) error {
156
+ func (b * ElasticSearchIndexer ) addDelete (filename string , repo * models.Repository ) ( []elastic.BulkableRequest , error ) {
156
157
id := filenameIndexerID (repo .ID , filename )
157
- reqs = append ( reqs ,
158
+ return []elastic. BulkableRequest {
158
159
elastic .NewBulkDeleteRequest ().
159
160
Index (b .indexerName ).
160
161
Id (id ),
161
- )
162
- return nil
162
+ }, nil
163
163
}
164
164
165
165
// Index will save the index data
166
166
func (b * ElasticSearchIndexer ) Index (repo * models.Repository , sha string , changes * repoChanges ) error {
167
167
reqs := make ([]elastic.BulkableRequest , 0 )
168
168
for _ , update := range changes .Updates {
169
- if err := b .addUpdate (sha , update , repo , reqs ); err != nil {
169
+ updateReqs , err := b .addUpdate (sha , update , repo )
170
+ if err != nil {
170
171
return err
171
172
}
173
+ if len (updateReqs ) > 0 {
174
+ reqs = append (reqs , updateReqs ... )
175
+ }
172
176
}
177
+
173
178
for _ , filename := range changes .RemovedFilenames {
174
- if err := b .addDelete (filename , repo , reqs ); err != nil {
179
+ delReqs , err := b .addDelete (filename , repo )
180
+ if err != nil {
175
181
return err
176
182
}
183
+ if len (delReqs ) > 0 {
184
+ reqs = append (reqs , delReqs ... )
185
+ }
177
186
}
178
187
179
188
if len (reqs ) > 0 {
@@ -188,15 +197,13 @@ func (b *ElasticSearchIndexer) Index(repo *models.Repository, sha string, change
188
197
189
198
// Delete deletes indexes by ids
190
199
func (b * ElasticSearchIndexer ) Delete (repoID int64 ) error {
191
- _ , err := b .client .Delete ().
192
- Index (b .indexerName ).
200
+ _ , err := b .client .DeleteByQuery (b .indexerName ).
193
201
Query (elastic .NewTermsQuery ("repo_id" , repoID )).
194
202
Do (context .Background ())
195
203
return err
196
204
}
197
205
198
- // Search searches for issues by given conditions.
199
- // Returns the matching issue IDs
206
+ // Search searches for codes and language stats by given conditions.
200
207
func (b * ElasticSearchIndexer ) Search (repoIDs []int64 , language , keyword string , page , pageSize int ) (int64 , []* SearchResult , []* SearchResultLanguages , error ) {
201
208
kwQuery := elastic .NewMultiMatchQuery (keyword , "content" )
202
209
query := elastic .NewBoolQuery ()
@@ -209,38 +216,47 @@ func (b *ElasticSearchIndexer) Search(repoIDs []int64, language, keyword string,
209
216
repoQuery := elastic .NewTermsQuery ("repo_id" , repoStrs ... )
210
217
query = query .Must (repoQuery )
211
218
}
219
+ start := 0
220
+ if page > 0 {
221
+ start = (page - 1 ) * pageSize
222
+ }
212
223
searchResult , err := b .client .Search ().
213
224
Index (b .indexerName ).
214
225
Query (query ).
215
- Sort ("id" , true ).
216
- From (page * pageSize ).Size (pageSize ).
226
+ Highlight (elastic .NewHighlight ().Field ("content" )).
227
+ Sort ("repo_id" , true ).
228
+ From (start ).Size (pageSize ).
217
229
Do (context .Background ())
218
230
if err != nil {
219
231
return 0 , nil , nil , err
220
232
}
221
233
234
+ var kw = "<em>" + keyword + "</em>"
235
+
222
236
hits := make ([]* SearchResult , 0 , pageSize )
223
237
for _ , hit := range searchResult .Hits .Hits {
224
238
var startIndex , endIndex int = - 1 , - 1
225
- /*for _, locations := range hit.Fields["Content"] {
226
- location := locations[0]
227
- locationStart := int(location.Start)
228
- locationEnd := int(location.End)
229
- if startIndex < 0 || locationStart < startIndex {
230
- startIndex = locationStart
231
- }
232
- if endIndex < 0 || locationEnd > endIndex {
233
- endIndex = locationEnd
239
+ c , ok := hit .Highlight ["content" ]
240
+ if ok && len (c ) > 0 {
241
+ startIndex = strings .Index (c [0 ], kw )
242
+ if startIndex > - 1 {
243
+ endIndex = startIndex + len (kw )
234
244
}
235
- }*/
245
+ }
246
+
236
247
repoID , fileName := parseIndexerID (hit .Id )
237
- hits = append ( hits , & SearchResult {
248
+ var h = SearchResult {
238
249
RepoID : repoID ,
239
250
StartIndex : startIndex ,
240
251
EndIndex : endIndex ,
241
252
Filename : fileName ,
242
- Content : hit .Fields ["content" ].(string ),
243
- })
253
+ }
254
+
255
+ if err := json .Unmarshal (hit .Source , & h ); err != nil {
256
+ return 0 , nil , nil , err
257
+ }
258
+
259
+ hits = append (hits , & h )
244
260
}
245
261
246
262
return searchResult .TotalHits (), hits , nil , nil
0 commit comments