mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-06 19:38:36 +08:00
fix(go-skill): Elasticsearch skill search field mapping (#16611)
## Summary
Fix Elasticsearch-backed skill search by mapping skill search fields to
their indexed token fields.
`name`, `tags`, `description`, and `content` are stored for display but
are not searchable in the skill ES mapping. Search queries now target
`name_tks`, `tags_tks`, `description_tks`, and `content_tks`.
## Testing
- Ran Go unit tests:
```bash
/usr/local/go/bin/go test -count=1 ./internal/engine/elasticsearch
```
- Frontend verification:
1. Open /files/skills.
2. Enter a skill space.
3. Reindex the skill space if existing skills were created before this
fix.
4. Search by skill name or description keyword.
5. Confirm matching skills are returned.
This commit is contained in:
@@ -1746,6 +1746,9 @@ func buildQueryStringQuery(matchText *types.MatchTextExpr, vectorSimilarityWeigh
|
||||
fields = []string{"title_tks^10", "title_sm_tks^5", "important_kwd^30", "important_tks^20", "question_tks^20", "content_ltks^2", "content_sm_ltks"}
|
||||
}
|
||||
}
|
||||
if isSkillIndex {
|
||||
fields = mapSkillSearchFields(fields)
|
||||
}
|
||||
if isMemoryIndex {
|
||||
fields = mapMemoryMessageESFields(fields, true)
|
||||
}
|
||||
@@ -1768,6 +1771,29 @@ func buildQueryStringQuery(matchText *types.MatchTextExpr, vectorSimilarityWeigh
|
||||
}
|
||||
}
|
||||
|
||||
func mapSkillSearchFields(fields []string) []string {
|
||||
mapped := make([]string, 0, len(fields))
|
||||
for _, field := range fields {
|
||||
name, boost, hasBoost := strings.Cut(field, "^")
|
||||
switch name {
|
||||
case "name":
|
||||
name = "name_tks"
|
||||
case "tags":
|
||||
name = "tags_tks"
|
||||
case "description":
|
||||
name = "description_tks"
|
||||
case "content":
|
||||
name = "content_tks"
|
||||
}
|
||||
if hasBoost {
|
||||
mapped = append(mapped, name+"^"+boost)
|
||||
} else {
|
||||
mapped = append(mapped, name)
|
||||
}
|
||||
}
|
||||
return mapped
|
||||
}
|
||||
|
||||
// buildRankFeatureQuery builds rank_feature queries for learning to rank
|
||||
func buildRankFeatureQuery(rankFeature map[string]float64) []map[string]interface{} {
|
||||
if rankFeature == nil || len(rankFeature) == 0 {
|
||||
|
||||
@@ -4,8 +4,37 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"ragflow/internal/engine/types"
|
||||
)
|
||||
|
||||
func TestBuildQueryStringQueryMapsSkillFieldsToTokenFields(t *testing.T) {
|
||||
query := buildQueryStringQuery(&types.MatchTextExpr{
|
||||
MatchingText: "test",
|
||||
Fields: []string{"name^10", "tags^5", "description^3", "content^1"},
|
||||
}, 0, true, false)
|
||||
|
||||
queryString, ok := query["query_string"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("query_string missing from %#v", query)
|
||||
}
|
||||
assertEqual(t, queryString["fields"], []string{"name_tks^10", "tags_tks^5", "description_tks^3", "content_tks^1"})
|
||||
assertEqual(t, queryString["query"], "test")
|
||||
}
|
||||
|
||||
func TestBuildQueryStringQueryKeepsDocumentFieldsUnchanged(t *testing.T) {
|
||||
query := buildQueryStringQuery(&types.MatchTextExpr{
|
||||
MatchingText: "test",
|
||||
Fields: []string{"name^10"},
|
||||
}, 0, false, false)
|
||||
|
||||
queryString, ok := query["query_string"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("query_string missing from %#v", query)
|
||||
}
|
||||
assertEqual(t, queryString["fields"], []string{"name^10"})
|
||||
}
|
||||
|
||||
func TestElasticsearchGetFieldsFiltersAndUsesIDFallback(t *testing.T) {
|
||||
engine := &elasticsearchEngine{}
|
||||
chunks := []map[string]interface{}{
|
||||
|
||||
Reference in New Issue
Block a user