我收藏了一些文档,例如:
{
_id:"....",
resourceId: "375749d7-a828-4a7b-acc0-77539fbcb7b4" // string type
name: "bla random word"
}
有索引:
{
"mappings": {
"dynamic": false,
"fields": {
"name": {
"type": "autocomplete"
},
"resourceId": {
"type": "string"
}
}
}
}
我有一个 golang api 可以找到它
我想搜索名称或资源 ID 中包含精确内容的术语
例如,如果我发现像“bla”这样的部分名称会返回具有该名称的文档,如果我发现某些单词包含像“bla random”这样的所有单词
另一方面,如果我找到像“375749d7-a828-4a7b-acc0-77539fbcb7b4”或部分“375749d7”这样的id,则返回resourceId包含该术语的文档
我不确定索引是否正确,我尝试使用此代码
mustClauses := bson.A{
bson.D{
{Key: "$or", Value: bson.A{
bson.D{
{Key: "autocomplete", Value: bson.D{
{Key: "path", Value: "name"},
{Key: "query", Value: searchTerm},
}},
},
bson.D{
{Key: "regex", Value: bson.D{
{Key: "path", Value: "resourceId"},
{Key: "query", Value: searchTerm},
{Key: "allowAnalyzedField", Value: true},
}},
},
}},
},
}
search := bson.D{
{
Key: "$search", Value: bson.M{
"index": index,
"compound": bson.M{
"must": mustClauses,
},
},
},
}
但必须不能包含 $or,应该包含自动补全、正则表达式等
另一方面,我尝试使用 should 但返回不一致的文档(如果您搜索“bla random”返回仅包含“bla”等的文档)
有人知道如何实现吗?
在我寻求解决方案后,我看到了一个解决方案,索引没问题,但 golang 代码应该更改
func buildSearch(locale string, searchTerm string, index string) bson.D {
var arrayFilter = addLocaleFilter(locale)
addTextFilters(&arrayFilter, searchTerm)
search := bson.D{
{
Key: "$search", Value: bson.M{
"index": index,
"compound": bson.M{
"must": arrayFilter,
},
"count": bson.D{
{Key: "type", Value: "total"},
},
},
},
}
return search
}
func addTextFilters(arrayFilter *bson.A, text string) {
if text != "" {
textFilters :=
bson.A{
addAutocompleteFilterWithBoost(text, "name", NameScore),
addTextFilterWithBoost(text, "resourceId", ResourceIdScore),
}
*arrayFilter = append(*arrayFilter, bson.D{
{Key: "compound",
Value: bson.M{
"should": textFilters,
},
},
})
}
}
func addTextFilterWithBoost(term string, path string, score int) bson.D {
return bson.D{
{Key: "text", Value: bson.D{
{Key: "path", Value: bson.A{path}},
{Key: "query", Value: term},
{Key: "score", Value: bson.D{
{Key: "boost", Value: bson.D{
{Key: "value", Value: score},
}},
}},
}},
}
}
func addAutocompleteFilterWithBoost(term string, path string, score int) bson.D {
return bson.D{
{Key: "autocomplete", Value: bson.D{
{Key: "path", Value: path},
{Key: "query", Value: term},
{Key: "score", Value: bson.D{
{Key: "boost", Value: bson.D{
{Key: "value", Value: score},
}},
}},
}},
}
}