Skip to content

Commit a2d5c5c

Browse files
committed
add line
1 parent 3b38e4d commit a2d5c5c

File tree

6 files changed

+100
-57
lines changed

6 files changed

+100
-57
lines changed

internal/logic/embedding_task.go

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -719,28 +719,11 @@ func (l *TaskLogic) deleteFilesFromVectorDB(ctx context.Context, codebase *model
719719

720720
l.Logger.Infof("准备从向量数据库中删除 %d 个文件,代码库ID: %d", len(filePaths), codebase.ID)
721721

722-
// 构建需要删除的 CodeChunk 列表
723-
var chunks []*types.CodeChunk
724722
for _, filePath := range filePaths {
725723
// 将文件路径转换为Linux格式(正斜杠)
726724
linuxPath := strings.ReplaceAll(filePath, "\\", "/")
727-
chunk := &types.CodeChunk{
728-
CodebaseId: codebase.ID,
729-
CodebasePath: codebase.Path,
730-
FilePath: linuxPath,
731-
}
732-
chunks = append(chunks, chunk)
733725
l.Logger.Debugf("添加文件到删除列表: %s", linuxPath)
734-
}
735-
736-
// 调用向量数据库的删除方法
737-
options := vector.Options{
738-
CodebasePath: codebase.Path,
739-
}
740-
err := l.svcCtx.VectorStore.DeleteCodeChunks(ctx, chunks, options)
741-
if err != nil {
742-
l.Logger.Errorf("删除向量数据库中的文件失败: %v", err)
743-
return fmt.Errorf("failed to delete files from vector database: %w", err)
726+
l.svcCtx.VectorStore.DeleteDictionary(ctx, filePath, vector.Options{CodebaseId: codebase.ID, CodebasePath: codebase.Path})
744727
}
745728

746729
l.Logger.Infof("成功从向量数据库中删除了 %d 个文件", len(filePaths))

internal/logic/index.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
78
"github.com/zgsm-ai/codebase-indexer/internal/store/vector"
89
"github.com/zgsm-ai/codebase-indexer/internal/tracer"
9-
"strings"
1010

1111
"github.com/zgsm-ai/codebase-indexer/internal/errs"
1212
"gorm.io/gorm"
@@ -55,17 +55,7 @@ func (l *IndexLogic) DeleteIndex(req *types.DeleteIndexRequest) (resp *types.Del
5555
return &types.DeleteIndexResponseData{}, nil
5656
}
5757

58-
// 如果指定了filePaths,则只删除指定文件的嵌入数据
59-
var deleteChunks []*types.CodeChunk
60-
for _, path := range strings.Split(filePaths, ",") {
61-
deleteChunks = append(deleteChunks, &types.CodeChunk{
62-
CodebaseId: codebase.ID,
63-
CodebasePath: codebase.Path,
64-
FilePath: strings.TrimSpace(path),
65-
})
66-
}
67-
68-
if err = l.svcCtx.VectorStore.DeleteCodeChunks(ctx, deleteChunks, vector.Options{CodebaseId: codebase.ID,
58+
if err = l.svcCtx.VectorStore.DeleteDictionary(ctx, filePaths, vector.Options{CodebaseId: codebase.ID,
6959
CodebasePath: codebase.Path}); err != nil {
7060
return nil, fmt.Errorf("failed to delete embedding index, err:%w", err)
7161
}

internal/logic/semantic.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@ package logic
22

33
import (
44
"context"
5-
"errors"
6-
"fmt"
75

86
"github.com/zgsm-ai/codebase-indexer/internal/errs"
97
"github.com/zgsm-ai/codebase-indexer/internal/store/vector"
108
"github.com/zgsm-ai/codebase-indexer/internal/tracer"
119
"github.com/zgsm-ai/codebase-indexer/pkg/utils"
12-
"gorm.io/gorm"
1310

1411
"github.com/zgsm-ai/codebase-indexer/internal/svc"
1512
"github.com/zgsm-ai/codebase-indexer/internal/types"
@@ -51,21 +48,15 @@ func (l *SemanticLogic) SemanticSearch(req *types.SemanticSearchRequest, authori
5148
if err != nil {
5249
return nil, err
5350
}
54-
clientId := req.ClientId
55-
clientPath := req.CodebasePath
5651

57-
codebase, err := l.svcCtx.Querier.Codebase.FindByClientIdAndPath(l.ctx, clientId, clientPath)
58-
if errors.Is(err, gorm.ErrRecordNotFound) {
59-
return nil, errs.NewRecordNotFoundErr(types.NameCodeBase, fmt.Sprintf("client_id: %s, clientPath: %s", clientId, clientPath))
60-
}
61-
ctx := context.WithValue(l.ctx, tracer.Key, tracer.RequestTraceId(int(codebase.ID)))
52+
ctx := context.WithValue(l.ctx, tracer.Key, req.ClientId)
6253

6354
documents, err := l.svcCtx.VectorStore.Query(ctx, req.Query, topK,
6455
vector.Options{
65-
CodebaseId: codebase.ID,
66-
ClientId: clientId,
67-
CodebasePath: codebase.Path,
68-
CodebaseName: codebase.Name,
56+
CodebaseId: 0,
57+
ClientId: req.ClientId,
58+
CodebasePath: req.CodebasePath,
59+
CodebaseName: "",
6960
Authorization: authorization,
7061
})
7162
if err != nil {

internal/store/vector/vector_store.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type Store interface {
2020
InsertCodeChunks(ctx context.Context, docs []*types.CodeChunk, options Options) error
2121
UpsertCodeChunks(ctx context.Context, chunks []*types.CodeChunk, options Options) error
2222
DeleteCodeChunks(ctx context.Context, chunks []*types.CodeChunk, options Options) error
23+
DeleteDictionary(ctx context.Context, dictionary string, options Options) error
2324
UpdateCodeChunksPaths(ctx context.Context, updates []*types.CodeChunkPathUpdate, options Options) error
2425
UpdateCodeChunksDictionary(ctx context.Context, codebasePath string, dictionary string, newDictionary string) error
2526
Query(ctx context.Context, query string, topK int, options Options) ([]*types.SemanticFileItem, error)

internal/store/vector/weaviate_wrapper.go

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -335,18 +335,19 @@ func (r *weaviateWrapper) unmarshalSimilarSearchResponse(res *models.GraphQLResp
335335
content := ""
336336
filePath := getStringValue(obj, MetadataFilePath)
337337

338+
// 从MetadataRange中提取startLine和endLine(用于构建映射键)
339+
var startLine, endLine int
340+
if rangeValue, ok := obj[MetadataRange].([]interface{}); ok && len(rangeValue) >= 2 {
341+
if first, ok := rangeValue[0].(float64); ok {
342+
startLine = int(first)
343+
}
344+
if second, ok := rangeValue[2].(float64); ok {
345+
endLine = int(second)
346+
}
347+
}
348+
338349
// 如果开启获取源码且有批量获取的内容,则使用获取到的内容
339350
if r.cfg.FetchSourceCode && filePath != "" && codebasePath != "" {
340-
// 从MetadataRange中提取startLine和endLine(用于构建映射键)
341-
var startLine, endLine int
342-
if rangeValue, ok := obj[MetadataRange].([]interface{}); ok && len(rangeValue) >= 2 {
343-
if first, ok := rangeValue[0].(float64); ok {
344-
startLine = int(first)
345-
}
346-
if second, ok := rangeValue[2].(float64); ok {
347-
endLine = int(second)
348-
}
349-
}
350351

351352
// 构建映射键并查找批量获取的内容
352353
fullPath := filepath.Join(codebasePath, filePath)
@@ -358,9 +359,11 @@ func (r *weaviateWrapper) unmarshalSimilarSearchResponse(res *models.GraphQLResp
358359

359360
// Create SemanticFileItem with proper fields
360361
item := &types.SemanticFileItem{
361-
Content: content,
362-
FilePath: filePath,
363-
Score: float32(getFloatValue(additional, "certainty")), // Convert float64 to float32
362+
Content: content,
363+
FilePath: filePath,
364+
StartLine: startLine,
365+
EndLine: endLine,
366+
Score: float32(getFloatValue(additional, "certainty")), // Convert float64 to float32
364367
}
365368

366369
items = append(items, item)
@@ -1423,6 +1426,79 @@ func (r *weaviateWrapper) getRecordsByPathPrefix(ctx context.Context, pathPrefix
14231426
return r.unmarshalRecordsResponse(res)
14241427
}
14251428

1429+
// DeleteDictionary 删除指定目录的记录,通过匹配filePath的前缀
1430+
func (r *weaviateWrapper) DeleteDictionary(ctx context.Context, dictionary string, options Options) error {
1431+
// 生成租户名称
1432+
tenantName, err := r.generateTenantName(options.CodebasePath)
1433+
if err != nil {
1434+
return fmt.Errorf("failed to generate tenant name: %w", err)
1435+
}
1436+
1437+
// 确保路径前缀以/结尾,以便正确匹配子目录和文件
1438+
if dictionary != "" && !strings.HasSuffix(dictionary, "/") {
1439+
dictionary += "/"
1440+
}
1441+
1442+
// 获取所有匹配目录前缀的记录
1443+
records, err := r.getRecordsByPathPrefix(ctx, dictionary, tenantName)
1444+
if err != nil {
1445+
return fmt.Errorf("failed to get records by path prefix: %w", err)
1446+
}
1447+
1448+
if len(records) == 0 {
1449+
// 没有找到需要删除的记录
1450+
return nil
1451+
}
1452+
1453+
// 将记录转换为CodeChunk格式以便删除
1454+
chunks := make([]*types.CodeChunk, 0, len(records))
1455+
for _, record := range records {
1456+
chunk := &types.CodeChunk{
1457+
CodebaseId: record.CodebaseId,
1458+
FilePath: record.FilePath,
1459+
}
1460+
chunks = append(chunks, chunk)
1461+
}
1462+
1463+
if len(chunks) > 0 {
1464+
chunkFilters := make([]*filters.WhereBuilder, len(chunks))
1465+
for i, chunk := range chunks {
1466+
if chunk.FilePath == types.EmptyString {
1467+
return fmt.Errorf("invalid chunk to delete: and filePath")
1468+
}
1469+
chunkFilters[i] = filters.Where().
1470+
WithOperator(filters.And).
1471+
WithOperands([]*filters.WhereBuilder{
1472+
filters.Where().
1473+
WithPath([]string{MetadataCodebaseId}).
1474+
WithOperator(filters.Equal).
1475+
WithValueInt(int64(chunk.CodebaseId)),
1476+
filters.Where().
1477+
WithPath([]string{MetadataFilePath}).
1478+
WithOperator(filters.Equal).
1479+
WithValueText(chunk.FilePath),
1480+
})
1481+
}
1482+
1483+
// Combine all chunk filters with OR to support batch deletion of files
1484+
combinedFilter := filters.Where().
1485+
WithOperator(filters.Or).
1486+
WithOperands(chunkFilters)
1487+
1488+
do, err := r.client.Batch().ObjectsBatchDeleter().
1489+
WithTenant(tenantName).WithWhere(
1490+
combinedFilter,
1491+
).WithClassName(r.className).Do(ctx)
1492+
if err != nil {
1493+
return fmt.Errorf("failed to send delete chunks err:%w", err)
1494+
}
1495+
return CheckBatchDeleteErrors(do)
1496+
}
1497+
1498+
// 批量删除记录
1499+
return nil
1500+
}
1501+
14261502
// UpdateCodeChunksDictionary 更新代码块的目录路径,通过匹配filePath的前缀
14271503
func (r *weaviateWrapper) UpdateCodeChunksDictionary(ctx context.Context, codebasePath string, dictionary string, newDictionary string) error {
14281504
// 生成租户名称

internal/types/req.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)