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 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误