How to recover the struct from a Document in Golang package, Bleve

237 views Asked by At

It would be most convenient if I was able to get back the indexed struct from my Bleve SearchResults. This is what I know and what I have: I have SearchResults.Hits which I can iterate over, and get the Document with index.Document(hit.ID). With the document, I also have access to its fields. What I could do is manually reconstruct the struct. However, in another question about Bleve on here it was mentioned that one can use index.GetInternal(hit.ID) to get back the original struct, if Index Internal has been set. There is index.SetInternal(key, val []byte) error, but I am very much at a loss for how to use this accomplish what I wish to. I dug in to the code, but it honestly didn't offer my limited knowledge any insight. How could I set it up so that I only need to invoke index.GetInternal to retrieve a struct from my search results?

1

There are 1 answers

0
quanta On

Marty Schoch does not recommend that solution anymore.

What he suggested instead is:

  • encode your struct:
    doc := document.Document{
        ID: post.URI,
    }
    if err := bleve.NewIndexMapping().MapDocument(&doc, post); err != nil {
        return errors.Errorf("failed to map document: %v", err)
    }

    var b bytes.Buffer
    enc := gob.NewEncoder(&b)
    if err := enc.Encode(post); err != nil {
        return errors.Errorf("failed to encode post: %v", err)
    }
  • add a new field to store encoded bytes:
    field := document.NewTextFieldWithIndexingOptions("_source", nil, b.Bytes(), document.StoreField)
    if err := batch.IndexAdvanced(doc.AddField(field)); err != nil {
        return errors.Errorf("failed to add index to the batch: %v", err)
    }
  • decode the search results:
    query := bleve.NewMatchQuery(value)
    request := bleve.NewSearchRequest(query)
    request.Fields = []string{"_source"}
    searchResults, err := ps.index.Search(request)
    if err != nil {
        return nil, errors.Errorf("failed to execute a search request: %v", err)
    }

    var searchPosts []*blog.Post
    for _, result := range searchResults.Hits {
        var post *blog.Post
        b := bytes.NewBuffer([]byte(fmt.Sprintf("%v", result.Fields["_source"])))
        dec := gob.NewDecoder(b)
        if err = dec.Decode(&post); err != nil {
            return nil, errors.Errorf("failed to decode post: %v", err)
        }
        searchPosts = append(searchPosts, post)
    }

Source: https://gist.github.com/michaeljs1990/25f9949c10ab64d971422dda44feea0e