4
votes

I am trying to perform a filter query on a set of entities in the datastore, but the entity field I am trying to query against, with the equality operator, is of type []byte and I don't know if appengine datastore can perform this comparison

This is my entity:

type Data struct {
 Id          int64  `json:"id"`
 Version     int32  `json:"-"`
 HMAC        []byte `json:"-"`
 Status      string `json:"status"`
}

And here is my query logic

func (view *DataView) GetDataByHMAC(hmac []byte) (Data, error) {
    view_key := datastore.NewKey(view.context, "View", "data-view", 0, nil)
    data := make([]Data, 0)
    query := datastore.
       NewQuery("ViewData").
       Ancestor(view_key).
       Filter("HMAC = ", hmac)
    _, err := query.GetAll(view.context, &data)
    if err != nil {
       return Data{}, err
    }
    if len(data) == 0 {
       return Data{}, ErrNoData
    }
    return data[0], nil
}

It builds but does not return any results, even after programmatically retrying over the course of 10 seconds so i do not believe it is an issue of eventual consistency between the datastore and the view data that I've stored there.

My main question is: does the appengine datastore allow for a query to use a comparison filter on a field with type []byte?

2
what is the question?OneOfOne
Sorry i made it explicit nowInternetProfessionalPersonHere
Before I spend any time on this remove the trailing space in the Filter string "HMAC = " and see what happens.AndrewN
I see no change in behavior and all of my other queries include both optional spaces and return results accurately; I hadn't thought of checking though, thanksInternetProfessionalPersonHere
Cant you just store the []byte as a string?RickyA

2 Answers

4
votes

In 1.9.11, the ByteString type was introduced to the datastore package. It can be used for storing short, indexed byte slices.

If you change your entity to the following, it should work:

type Data struct {
  ID      int64                `json:"id"`
  Version int32                `json:"-"`
  HMAC    datastore.ByteString `json:"-"`
  Status  string               `json:"status"`
}

More info: https://developers.google.com/appengine/docs/go/datastore/entities#Go_Properties_and_value_types

3
votes

The answer to your main question is No, because []byte is stored as blob, which is not indexed by the app engine datastore.

queries with a filter or sort order on the unindexed property 
will never match that entity.
Note: In addition to any unindexed properties you declare explicitly, 
those typed as []byte are automatically treated as unindexed.

Here is the documentation: https://developers.google.com/appengine/docs/go/datastore/indexes#Go_Unindexed_properties