如何在 golang 的 elasticsearch 文档(索引)中搜索字符串?

How to search a string in the elasticsearch document(indexed) in golang?

我正在用 golang 编写一个函数来在索引的 elasticsearch 文档中搜索字符串。我正在使用 elasticsearch golang 客户端 elastic。例如考虑对象是 tweet,

type Tweet struct {
    User    string
    Message string
    Retweets int
}

并且搜索功能是

func SearchProject() error{
    // Search with a term query
    termQuery := elastic.NewTermQuery("user", "olivere")
    searchResult, err := client.Search().
        Index("twitter").   // search in index "twitter"
        Query(&termQuery).  // specify the query
        Sort("user", true). // sort by "user" field, ascending
        From(0).Size(10).   // take documents 0-9
        Pretty(true).       // pretty print request and response JSON
        Do()                // execute
    if err != nil {
        // Handle error
        panic(err)
        return err
    }

    // searchResult is of type SearchResult and returns hits, suggestions,
    // and all kinds of other information from Elasticsearch.
    fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis)

    // Each is a convenience function that iterates over hits in a search result.
    // It makes sure you don't need to check for nil values in the response.
    // However, it ignores errors in serialization. If you want full control
    // over iterating the hits, see below.
    var ttyp Tweet
    for _, item := range searchResult.Each(reflect.TypeOf(ttyp)) {
        t := item.(Tweet)
        fmt.Printf("Tweet by %s: %s\n", t.User, t.Message)
    }
    // TotalHits is another convenience function that works even when something goes wrong.
    fmt.Printf("Found a total of %d tweets\n", searchResult.TotalHits())

    // Here's how you iterate through results with full control over each step.
    if searchResult.Hits != nil {
        fmt.Printf("Found a total of %d tweets\n", searchResult.Hits.TotalHits)

        // Iterate through results
        for _, hit := range searchResult.Hits.Hits {
            // hit.Index contains the name of the index

            // Deserialize hit.Source into a Tweet (could also be just a map[string]interface{}).
            var t Tweet
            err := json.Unmarshal(*hit.Source, &t)
            if err != nil {
                // Deserialization failed
            }

            // Work with tweet
            fmt.Printf("Tweet by %s: %s\n", t.User, t.Message)
        }
    } else {
        // No hits
        fmt.Print("Found no tweets\n")
    }
    return nil
}

此搜索正在打印用户 'olivere' 的推文。但是如果我给 'olive' 那么搜索就不起作用了。如何搜索属于 User/Message/Retweets 的字符串?

索引函数如下所示,

func IndexProject(p *objects.ElasticProject) error {
// Index a tweet (using JSON serialization)
    tweet1 := `{"user" : "olivere", "message" : "It's a Raggy Waltz"}`
    put1, err := client.Index().
        Index("twitter").
        Type("tweet").
        Id("1").
        BodyJson(tweet1).
        Do()
    if err != nil {
        // Handle error
        panic(err)
        return err
    }
    fmt.Printf("Indexed tweet %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type)

    return nil
}

输出:

Indexed tweet 1 to index twitter, type tweet
Got document 1 in version 1 from index twitter, type tweet
Query took 4 milliseconds
Tweet by olivere: It's a Raggy Waltz
Found a total of 1 tweets
Found a total of 1 tweets
Tweet by olivere: It's a Raggy Waltz

版本

Go 1.4.2
Elasticsearch-1.4.4

Elasticsearch Go 库

github.com/olivere/elastic

谁能帮我解决这个问题。?谢谢

您如何搜索和查找数据取决于您的分析器 - 从您的代码来看,很可能正在使用标准分析器(即您没有在映射中指定替代项)。

Standard Analyser 只会索引完整的单词。因此,要将 "olive" 与 "olivere" 匹配,您可以:

  1. 更改搜索过程

例如从术语查询切换到带通配符的 Prefix query or use a Query String query

  1. 更改索引进程

如果您想在较大的字符串中查找字符串,请考虑在您的分析器中使用 nGrams or Edge nGrams

multiQuery := elastic.NewMultiMatchQuery(
    term,
    "name", "address", "location", "email", "phone_number", "place", "postcode",
).Type("phrase_prefix")