dtnqbre7980007 2015-03-20 07:43
浏览 226
已采纳

如何在Golang的Elasticsearch文档(已索引)中搜索字符串?

I am writing a function in golang to search for a string in elasticsearch documents which are indexed. I am using elasticsearch golang client elastic. For example consider the object is tweet,

type Tweet struct {
    User    string
    Message string
    Retweets int
}

And the search function is

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
", 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
", t.User, t.Message)
    }
    // TotalHits is another convenience function that works even when something goes wrong.
    fmt.Printf("Found a total of %d tweets
", 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
", 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
", t.User, t.Message)
        }
    } else {
        // No hits
        fmt.Print("Found no tweets
")
    }
    return nil
}

This search is printing tweets by the user 'olivere'. But if I give 'olive' then search is not working. How do I search for a string which is part of User/Message/Retweets?

And the Indexing function looks like this,

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
", put1.Id, put1.Index, put1.Type)

    return nil
}

Output:

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

Version

Go 1.4.2
Elasticsearch-1.4.4

Elasticsearch Go Library

github.com/olivere/elastic

Could anyone help me on this.? Thank you

  • 写回答

1条回答 默认 最新

  • dongyuanliao6204 2015-03-20 12:09
    关注

    How you search and find data depends on your analyser - from your code it's likely that the standard analyser is being used (i.e. you haven't specified an alternative in your mapping).

    The Standard Analyser will only index complete words. So to match "olive" against "olivere" you could either:

    1. Change the search process

    e.g. switch from a term query to a Prefix query or use a Query String query with a wildcard.

    1. Change the index process

    If you want to find strings within larger strings then look at using nGrams or Edge nGrams in your analyser.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突