Connor McCutcheon Connor McCutcheon - 5 months ago 17
Node.js Question

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.

Answer

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
  })