5

I am new to Go and Bleve (sorry if I'm asking trivial things…). This search engine seems to be really nice, but I am getting stuck when it comes to deal with my search results.

Let's say we have a struct:

type Person struct {
    Name string `json:"name"`
    Bio  string `json:"bio"`
}

Now, we extract data from the database (using sqlx lib):

rows := []Person{}
db.Select(&rows, "SELECT * FROM person")

...and index it:

index.Index, err = bleve.Open("index.bleve")

batch := index.Index.NewBatch()

i := 0
for _, row := range rows {
    rowId := fmt.Sprintf("%T_%d", row, row.ID)
    batch.Index(rowId, row)

    i++
    if i > 100 {
        index.Index.Batch(batch)
        i = 0
    }
}

Now we have our index created. It works great.

Using the bleve command line utility, it returns data correctly:

bleve query index.bleve doe

3 matches, showing 1 through 3, took 27.767838ms
    1. Person_68402 (0.252219)
    Name
        Doe
    Bio
        My name is John Doe!

    2. ...

Here we see that bleve has stored Name and Bio fields.

Now I want to do it to access it from my code!

query := bleve.NewMatchAllQuery()
searchRequest := bleve.NewSearchRequest(query)
searchResults, _ := index.Index.Search(searchRequest)

fmt.Println(searchResults[0].ID) // <- This works

But I don't only want the ID and then query the database to get the rest of the date. To avoid hitting database, I would like to be able to do something like:

fmt.Println(searchResults[0].Bio) // <- This doesn't work :(

Could you please help?

user650108
  • 1,009
  • 1
  • 9
  • 18

1 Answers1

9

Every hit in the search result is a DocumentMatch. You can see in the documentation that DocumentMatch has Fields which is a map[string]interface{} and can be accessed as follows:

searchResults.Hits[0].Fields["Bio"].(string)

Bleve doesn't include the document's fields in the results by default. You must provide a list of the fields you'd like returned to SearchRequest.Fields (the argument to index.Search). Alternatively, you can set

searchRequest.Fields = []string{"*"}

to return all fields.

Eric Lindsey
  • 954
  • 8
  • 19
Zippo
  • 15,850
  • 10
  • 60
  • 58
  • Thank you very much Moshe, it works like a charm! Fields are located in Hits, so I had to do a searchResults.Hits[0].Fields["Bio"] to get it. – user650108 May 28 '18 at 21:45
  • @user650108 Good catch ;-) – Zippo May 30 '18 at 20:42
  • 「Alternatively, you can pass []string{"*"} to return all fields.」, pass to where? – navono Sep 25 '20 at 09:17
  • 1
    Just for note. Pass the Hits ID to index.Document will get fields, also if setup the index Internal, use index.GetInternal with Hits ID will get the original struct. – navono Sep 27 '20 at 00:10