node.jsgcloudgoogle-cloud-datastoregcloud-node

Google datastore precondition fail with timestamps


Hello I am trying to query google datastore entries from the node.js api. I have an entity which has an owner (string), a start time (date time) and an end time (date time) I am trying to query for all entities which match the given owner string and start after a given date with the following function (es2016).

static async getAvailability (owner, month = currentMonth) {
    const firstOfMonth = moment([currentYear, month])
    const query = datastore.createQuery('availability')
      .filter('owner', '=', owner)
      .filter('end', '>', firstOfMonth.toDate().toJSON())
      .order('end', {
        descending: true
      })
    try {
      // promise version of run query same function
      const result = await datastore.runQueryAsync(query)
      return result.map(result => {
        const { key, data } = result
        data._id = key.id
        return data
      })
    } catch (e) {
      console.log('error', e.stack)
      return []
    }
}

index.yaml indexes

- kind: availability
  properties:
  - name: owner
  - name: start
    direction: desc
  - name: end
    direction: desc

I am getting the error precondition failed error when i run the query. If there is any more information i can provide I would be more than happy.


Solution

  • Your query listed is only on owner and end. When you are using Cloud Datastore, the index you use has to exactly match the query.

    In the case of the query you listed, you need the index:

    - kind: availability
      properties:
      - name: owner
      - name: end
        direction: desc
    

    If you actually wanted your start date to be a specific time, your filter would have to be:

      .filter('start', '>', firstOfMonth.toDate().toJSON())
    

    And you would have to specify it first in your orders:

     .order('start')
     .order('end', {
        descending: true
      })