diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java index 63318a090..8e50d0867 100644 --- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java +++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java @@ -272,7 +272,10 @@ public Operator apply(String constant) { static final Operator GREATER_THAN = type.createAndRegister("GREATER_THAN"); static final Operator GREATER_THAN_OR_EQUAL = type.createAndRegister("GREATER_THAN_OR_EQUAL"); static final Operator EQUAL = type.createAndRegister("EQUAL"); + static final Operator IN = type.createAndRegister("IN"); + static final Operator NOT_EQUAL = type.createAndRegister("NOT_EQUAL"); static final Operator HAS_ANCESTOR = type.createAndRegister("HAS_ANCESTOR"); + static final Operator NOT_IN = type.createAndRegister("NOT_IN"); com.google.datastore.v1.PropertyFilter.Operator toPb() { return com.google.datastore.v1.PropertyFilter.Operator.valueOf(name()); @@ -502,6 +505,46 @@ public static PropertyFilter eq(String property, Blob value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } + public static PropertyFilter neq(String property, Value value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, value); + } + + public static PropertyFilter neq(String property, String value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter neq(String property, long value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter neq(String property, double value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter neq(String property, boolean value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter neq(String property, Timestamp value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter neq(String property, Key value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter neq(String property, Blob value) { + return new PropertyFilter(property, Operator.NOT_EQUAL, of(value)); + } + + public static PropertyFilter in(String property, ListValue value) { + return new PropertyFilter(property, Operator.IN, value); + } + + public static PropertyFilter not_in(String property, ListValue value) { + return new PropertyFilter(property, Operator.NOT_IN, value); + } + public static PropertyFilter hasAncestor(Key key) { return new PropertyFilter(KEY_PROPERTY_NAME, Operator.HAS_ANCESTOR, of(key)); } diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java index 3db8cfe3e..ac9ede3e9 100644 --- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java +++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java @@ -582,6 +582,64 @@ public void testRunStructuredQuery() throws InterruptedException { assertFalse(results4.hasNext()); } + @Test + public void testMoreQueryFilters() throws InterruptedException { + DATASTORE.put(ENTITY3); + + Query queryIn = + Query.newEntityQueryBuilder().setKind(KIND1) + .setFilter(PropertyFilter.in("age", ListValue.of(20, 30))).build(); + + Query scQueryIn = + Query.newEntityQueryBuilder() + .setKind(KIND1) + .setFilter(PropertyFilter.hasAncestor(ROOT_KEY)) + .setFilter(PropertyFilter.in("age", ListValue.of(20, 30))) + .build(); + + Iterator resultIn = getStronglyConsistentResults(scQueryIn, queryIn); + + assertTrue(resultIn.hasNext()); + assertEquals(ENTITY2, resultIn.next()); + assertFalse(resultIn.hasNext()); + + Query queryNotIn = + Query.newEntityQueryBuilder().setKind(KIND1) + .setFilter(PropertyFilter.not_in("age", ListValue.of(20, 30))).build(); + + Query scQueryNotIn = + Query.newEntityQueryBuilder() + .setKind(KIND1) + .setFilter(PropertyFilter.hasAncestor(ROOT_KEY)) + .setFilter(PropertyFilter.not_in("age", ListValue.of(20, 30))) + .build(); + + Iterator resultNotIn = getStronglyConsistentResults(scQueryNotIn, queryNotIn); + assertTrue(resultNotIn.hasNext()); + assertEquals(ENTITY1, resultNotIn.next()); + assertEquals(ENTITY3, resultIn.next()); + assertFalse(resultNotIn.hasNext()); + + Query queryNeq = + Query.newEntityQueryBuilder().setKind(KIND1) + .setFilter(PropertyFilter.neq("str", STR_VALUE)).build(); + + Query scQueryNeq = + Query.newEntityQueryBuilder() + .setKind(KIND1) + .setFilter(PropertyFilter.hasAncestor(ROOT_KEY)) + .setFilter(PropertyFilter.neq("str", STR_VALUE)) + .build(); + + Iterator resultNeq = getStronglyConsistentResults(scQueryNeq, queryNeq); + assertTrue(resultNeq.hasNext()); + assertEquals(ENTITY2, resultNeq.next()); + assertEquals(ENTITY3, resultNeq.next()); + assertFalse(resultNeq.hasNext()); + + DATASTORE.delete(ENTITY3.getKey()); + } + @Test public void testAllocateId() { KeyFactory keyFactory = DATASTORE.newKeyFactory().setKind(KIND1);