Mongo Atlas 搜索通过两个字段之一查找

问题描述 投票:0回答:1

我收藏了一些文档,例如:

{
_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”等的文档)

有人知道如何实现吗?

mongodb go full-text-search
1个回答
0
投票

在我寻求解决方案后,我看到了一个解决方案,索引没问题,但 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},
                }},
            }},
        }},
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.