Google Cloud Datastore runQuery returning 412 "no matching index found"
Asked Answered
K

4

5

** UPDATE **

Thanks to Alfred Fuller for pointing out that I need to create a manual index for this query.

Unfortunately, using the JSON API, from a .NET application, there does not appear to be an officially supported way of doing so. In fact, there does not officially appear to be a way to do this at all from an app outside of App Engine, which is strange since the Cloud Datastore API was designed to allow access to the Datastore outside of App Engine.

The closest hack I could find was to POST the index definition using RPC to http://appengine.google.com/api/datastore/index/add. Can someone give me the raw spec for how to do this exactly (i.e. URL parameters, what exactly should the body look like, etc), perhaps using Fiddler to inspect the call made by appcfg.cmd?

** ORIGINAL QUESTION **

According to the docs, "a query can combine equality (EQUAL) filters for different properties, along with one or more inequality filters on a single property".

However, this query fails:

{
 "query": {
  "kinds": [
   {
    "name": "CodeProse.Pogo.Tests.TestPerson"
   }
  ],
  "filter": {
   "compositeFilter": {
    "operator": "and",
    "filters": [
     {
      "propertyFilter": {
       "operator": "equal",
       "property": {
        "name": "DepartmentCode"
       },
       "value": {
        "integerValue": "123"
       }
      }
     },
     {
      "propertyFilter": {
       "operator": "greaterThan",
       "property": {
        "name": "HourlyRate"
       },
       "value": {
        "doubleValue": 50
       }
      }
     },
     {
      "propertyFilter": {
       "operator": "lessThan",
       "property": {
        "name": "HourlyRate"
       },
       "value": {
        "doubleValue": 100
       }
      }
     }
    ]
   }
  }
 }
}

with the following response:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "FAILED_PRECONDITION",
    "message": "no matching index found.",
    "locationType": "header",
    "location": "If-Match"
   }
  ],
  "code": 412,
  "message": "no matching index found."
 }
}
Katanga answered 2/7, 2013 at 16:58 Comment(0)
M
2

The error "no matching index found." indicates that an index needs to be added for the query to work. See the auto index generation documentation.

In this case you need an index with the properties DepartmentCode and HourlyRate (in that order).

Mazza answered 2/7, 2013 at 17:57 Comment(1)
Thanks Alfred! See my update to the question. Unfortunately I'm using the JSON API and am not using the App Engine SDK (which would allow me to easily include the index def file).Katanga
B
6

The JSON API does not yet support local index generation, but we've documented a process that you can follow to generate the xml definition of the index at https://developers.google.com/datastore/docs/tools/indexconfig#Datastore_Manual_index_configuration

Please give this a shot and let us know if it doesn't work.

This is a temporary solution that we hope to replace with automatic local index generation as soon as we can.

Bergstein answered 3/7, 2013 at 0:4 Comment(3)
Max - thanks, I saw this. I have no problem generating the XML index definition file. The question is - how do I upload it to the server? I don't have a Java or Python App Engine app...Katanga
Also, the next section of that doc refers to a GCD command line tool that looks like I could use to update the indexes on the server. Where can I find that tool?Katanga
@Katanga see developers.google.com/datastore/docs/tools/… on how to run gcd to update the index. You can download it from here: developers.google.com/datastore/docs/downloads#toolsGrandpapa
M
2

The error "no matching index found." indicates that an index needs to be added for the query to work. See the auto index generation documentation.

In this case you need an index with the properties DepartmentCode and HourlyRate (in that order).

Mazza answered 2/7, 2013 at 17:57 Comment(1)
Thanks Alfred! See my update to the question. Unfortunately I'm using the JSON API and am not using the App Engine SDK (which would allow me to easily include the index def file).Katanga
B
1

For gcloud-node I fixed it with those 3 links:

and most important link:

As explained in the last link, an index is what allows complex queries to run faster by storing the result set of the queries in an index. When you get no matching index found it means that you tried to run a complex query involving order or filter. So to make your query work, you need to create your index on the google datastore indexes by creating a config file manually to define your indexes that represent the query you are trying to run. Here is how you fix:

  1. create an index.yaml file in a folder named for example indexes in your app directory by following the directives for the python conf file: https://cloud.google.com/appengine/docs/python/config/indexconfig#Python_About_index_yaml or get inspiration from the gcloud-node tests in https://github.com/GoogleCloudPlatform/gcloud-node/blob/master/system-test/data/index.yaml
  2. create the indexes from the config file with this command: gcloud preview datastore create-indexes indexes/index.yaml see https://cloud.google.com/sdk/gcloud/reference/preview/datastore/create-indexes
  3. wait for the indexes to serve on your developer console in Cloud Datastore/Indexes, the interface should display "serving" once the index is built
  4. once it is serving your query should work

For example for this query:

 var q = ds.createQuery('project')
  .filter('tags =', category)
  .order('-date');

index.yaml looks like:

indexes:

- kind: project
  ancestor: no
  properties:
  - name: tags
  - name: date
    direction: desc
Bracy answered 10/8, 2015 at 20:44 Comment(0)
B
0

Try not to order the result. After removing orderby(), it worked for me.

Bristol answered 14/7, 2021 at 17:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.