Search code examples
javagoogle-app-enginegoogle-cloud-datastoregqlapp-engine-flexible

Issues with GQL query, Google Datastore. Error with multiple conditions and greater than and less than operators


I am trying to query the Datastore, and my query looks like this:

SELECT *
FROM mydb
WHERE Latitude = "18.1" AND Number > "1"

It doesn't work though. I get this error in the Datastore query box:

GQL query error: Your Datastore does not have the composite index (developer-supplied) required for this query.

And this error when I run my code:

no matching index found. recommended index is:\n- kind: mydb\n properties:\n - name: Location\n - name: Number\n

Simple requests like this work:

SELECT *
FROM mydb
WHERE Number > "1" AND Number < "5"

I am only accessing a single column here maybe that is why?

Nope,

Then I tried a request like this:

SELECT *
FROM mydb
WHERE Latitude = "18.1" AND Number = "1"

This worked.

I tried to look up a solution, and I came across this page: https://cloud.google.com/datastore/docs/tools/indexconfig#Datastore_About_index_yaml

After going through that page, I gathered that I need an index.yaml file somewhere. It is supposed to go in a folder called WEB-INF. But I don't have this folder.

This is a little snippet of my code:

Query<Entity> query = Query
                .gqlQueryBuilder(Query.ResultType.ENTITY,
                        "SELECT * FROM " + kind + " WHERE Location = @location AND Number <= @number")
                .setBinding("number", "5").setBinding("location", "18.1").build();
QueryResults<Entity> results = datastore.run(query);

Solution

  • The error you get is because the query you're attempting requires Composite indexes which are not available by default. They must be specified within index.yaml.

    The article Creating index files which is somewhat different than the one posted is specifically for Java applications running in the flexible environment.

    There are 2 ways to create an index.yaml:

    1. Manually using your favorite text editor following the rules and structure as prescribed in Index definitions.
    2. Generate the file as you test locally. This can be done using the gcloud beta emulators datastore start command. You can also use the --data-dir <dir> option to specify where the generated index.yaml should be written.

    Then, once you have index.yaml and the same directory as app.yaml, you can deploy it with gcloud preview app deploy index.yaml from that directory. This process is briefly documented in Deploying the index file.

    I would also recommend reading Organizing yaml Configuration Files.