// loadDoc converts from protobufs to a struct pointer or // FieldLoadSaver/FieldMetadataLoadSaver. The src param provides the document's // stored fields and facets, and any document metadata. An additional slice of // fields, exprs, may optionally be provided to contain any derived expressions // requested by the developer. func loadDoc(dst interface{}, src *pb.Document, exprs []*pb.Field) (err error) { fields, err := protoToFields(src.Field) if err != nil { return err } facets, err := protoToFacets(src.Facet) if err != nil { return err } if len(exprs) > 0 { exprFields, err := protoToFields(exprs) if err != nil { return err } // Mark each field as derived. for i := range exprFields { exprFields[i].Derived = true } fields = append(fields, exprFields...) } meta := &DocumentMetadata{ Rank: int(src.GetOrderId()), Facets: facets, } switch x := dst.(type) { case FieldLoadSaver: return x.Load(fields, meta) default: return loadStructWithMeta(dst, fields, meta) } }
// Next returns the ID of the next result. When there are no more results, // Done is returned as the error. // // dst must be a non-nil struct pointer, implement the FieldLoadSaver // interface, or be a nil interface value. If a non-nil dst is provided, it // will be filled with the indexed fields. dst is ignored if this iterator was // created with an IDsOnly option. func (t *Iterator) Next(dst interface{}) (string, error) { if t.err == nil && len(t.listRes)+len(t.searchRes) == 0 && t.more != nil { t.err = t.more(t) } if t.err != nil { return "", t.err } var doc *pb.Document var exprs []*pb.Field switch { case len(t.listRes) != 0: doc = t.listRes[0] t.listRes = t.listRes[1:] case len(t.searchRes) != 0: doc = t.searchRes[0].Document exprs = t.searchRes[0].Expression t.searchRes = t.searchRes[1:] default: return "", Done } if doc == nil { return "", errors.New("search: internal error: no document returned") } if !t.idsOnly && dst != nil { metadata := &DocumentMetadata{ Rank: int(doc.GetOrderId()), } if err := loadDoc(dst, doc.Field, exprs, metadata); err != nil { return "", err } } if t.limit > 0 { t.limit-- if t.limit == 0 { t.more = nil // prevent further fetches } } return doc.GetId(), nil }