Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doing a "IN Array" query on google app engine datastore with golang

Is there a way to do a query with ids []int64 on datastore? I've tried the following with no avail.

  1. Errors out

    q := datastore.NewQuery("Category").Filter("Id IN", ids)
    
  2. Just gets me all the the categories in the datastore

    for _, id := range ids {
        q.Filter("Id =", id)
    }
    

After icza's answer

var keys []*datastore.Key

for _, id := range ids {
    keys = append(keys, datastore.NewKey(c, "Category", "", id, nil))
}

categories := make([]Category, len(keys))
err := datastore.GetMulti(c, keys, categories)
if err != nil {
    return nil, err
}
like image 497
Steven Lu Avatar asked Mar 23 '15 02:03

Steven Lu


People also ask

How to query if an array contains a value in datdatastore?

Datastore mode indexes each unique array property value once per index. Thus to query if an array contains a value use an equality filter. Consider the following when your query includes properties with array values.

What is a datastore query?

A query retrieves entities from Cloud Firestore in Datastore mode that meet a specified set of conditions. The query operates on entities of a given kind; it can specify filters on the entities' property values, keys, and ancestors, and can return zero or more entities as results.

What is a query in FireStore?

A query retrieves entities from Firestore in Datastore mode that meet a specified set of conditions. The query operates on entities of a given kind ; it can specify filters on the entities' property values, keys, and ancestors, and can return zero or more entities as results.

How to check if an element exists or not in Golang?

This tutorial help to check an element exists or not in the golang array. You’ll have to develop your own function because Golang doesn’t have a generic method for this. We have created isElementExist functioN, This function will take arguments as a parameter : string : The array of source strings. str : The element to whome be search into source.


1 Answers

Generally "IN" filters are not supported by the Datastore. The documentation of Query.Filter() lists the allowed operators:

">", "<", ">=", "<=", or "="

What you can do is execute a separate query for each of the elements in the array you want to filter by. Also if the elements are in a continous range, you can substitute the IN with id>=min and id<=max. E.g.:

ids := []int64{1,2,3,4}
q := datastore.NewQuery("Category").Filter("Id>=", 1).Filter("Id<=", 4)

Also note that while the IN is not supported in general, if the property is the entity key itself, you can get a list of entities specified by an array of their keys using the datastore.GetMulti() function:

func GetMulti(c appengine.Context, key []*Key, dst interface{}) error

Note:

Your 2nd attempt returns all entities because you call Filter() on your query, but you don't store the return value, so the query you end up executing will have no filters at all. Query.Filter() returns a derivative query which contains the filter you just specified, you have to use the returned Query ongoing. So it should be:

q = q.Filter("Id=", id)

But even this won't work either: if multiple filters are specified, they will be in logical AND connection so it will most likely give you 0 results as I suspect no category will exists where Id is a list and which would contain all the ids you want to filter by.

like image 112
icza Avatar answered Sep 30 '22 17:09

icza