4

I want to search all entities whose name starts with a specific string, is this possible in Datastore?

I've tried this:

q = datastore.NewQuery("Places").Filter("Name > ", "a")

But it doesn't work.

If this is not possible, what alternative solution can you suggest to me? BigQuery? BigTable or other services on App Engine?

icza
  • 389,944
  • 63
  • 907
  • 827
Fantasim
  • 876
  • 1
  • 12
  • 32

1 Answers1

5

This is something that is possible, but with a combination of 2 inequality filters.

Let's say you want to list Places that have the "li" prefix. This can be described with a query that lists Places that are greater than (or equal to) "li" and less than a prefix that is the next string after "li" in lexicographical order: "lj".

This is how the GQL looks like:

SELECT * FROM Places WHERE Name > 'li' AND Name < 'lj'

Coded in Go it looks like this:

q = datastore.NewQuery("Places").Filter("Name >", "li").Filter("Name <", "lj")

This will list Places where name is for example:

liam
lisotto
lizst

But will exclude names like:

abc
ljoi
lj
qwerty

One thing to note: small and capital letters are different in lexicographical order, so for example "List" is less than "li" (even though "list" is greater than "li")!

icza
  • 389,944
  • 63
  • 907
  • 827
  • @Fantasim If an answer works and solves your problem, you should accpet it. You have many questions but you haven't accepted a single answer. There's a gray "tick" below the votes of the answer, you can accept it by clicking on that. Hovering the mouse over that will display a text: _"Click to accept this answer..."_ – icza Sep 01 '16 at 20:28
  • Could you precise in your answer why this solution doesn't work with an order filter ? – Fantasim Sep 02 '16 at 09:56
  • @Fantasim By "order filter" you mean a simple `.Filter("Name >", "li")`? Because this single filter will also accept `"ljoi"` for example, which does not have a `"li"` prefix. The 2nd filter `.Filter("Name <", "lj")` is needed to exclude everything whose prefix is "beyond" `"li"`. – icza Sep 02 '16 at 09:58
  • q = datastore.NewQuery("Places").Filter("Name >", "sorb").Filter("Name <", "sorc").Offset(0).Limit(10).Order("-PostNb") . If i put Order("-PostNb") query get me 0 entitie – Fantasim Sep 02 '16 at 10:00
  • 1
    @Fantasim Most likely because you don't have the appropriate index. Every search / filter operates on an index. Filtering by `Name` requires the `Name` property to be indexed. If you also want the results to be ordered by `PostNb`, you need an index that includes both. Also: _"...if a query specifies inequality filters on a property and sort orders on other properties, the property used in the inequality filters must be ordered before the other properties."_ ([source](https://cloud.google.com/appengine/docs/go/datastore/queries#sort_orders)) – icza Sep 02 '16 at 10:34