Browse Source

DATAMONGO-1808 - Polishing.

Move individual methods under BitwiseCriteriaOperators, update Javadoc and split tests.

Original Pull Request: #507
pull/549/merge
Christoph Strobl 8 years ago
parent
commit
b5f18468db
  1. 448
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java
  2. 55
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
  3. 301
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaTests.java
  4. 313
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java
  5. 1
      src/main/asciidoc/reference/mongodb.adoc

448
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java

@ -29,6 +29,7 @@ import java.util.stream.Collectors; @@ -29,6 +29,7 @@ import java.util.stream.Collectors;
import org.bson.BSON;
import org.bson.BsonRegularExpression;
import org.bson.Document;
import org.bson.types.Binary;
import org.springframework.data.domain.Example;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
@ -41,6 +42,7 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty; @@ -41,6 +42,7 @@ import org.springframework.data.mongodb.core.schema.JsonSchemaProperty;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -357,7 +359,7 @@ public class Criteria implements CriteriaDefinition { @@ -357,7 +359,7 @@ public class Criteria implements CriteriaDefinition {
/**
* Creates a criterion using the {@literal $type} operator.
*
* @param type must not be {@literal null}.
* @param types must not be {@literal null}.
* @return this
* @since 2.1
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/type/">MongoDB Query operator: $type</a>
@ -623,6 +625,18 @@ public class Criteria implements CriteriaDefinition { @@ -623,6 +625,18 @@ public class Criteria implements CriteriaDefinition {
return registerCriteriaChainElement(schemaCriteria);
}
/**
* Use {@link BitwiseCriteriaOperators} as gateway to create a criterion using one of the
* <a href="https://docs.mongodb.com/manual/reference/operator/query-bitwise/">bitwise operators</a> like
* {@code $bitsAllClear}.
*
* @return new instance of {@link BitwiseCriteriaOperators}. Never {@literal null}.
* @since 2.1
*/
public BitwiseCriteriaOperators bits() {
return new BitwiseCriteriaOperatorsImpl(this);
}
/**
* Creates an 'or' criteria using the $or operator for all of the provided criteria
* <p>
@ -664,118 +678,6 @@ public class Criteria implements CriteriaDefinition { @@ -664,118 +678,6 @@ public class Criteria implements CriteriaDefinition {
BasicDBList bsonList = createCriteriaList(criteria);
return registerCriteriaChainElement(new Criteria("$and").is(bsonList));
}
/**
* Creates a criterion using the {@literal $bitsAllClear} operator.
*
* @param numericBitmask non-negative numeric bitmask
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllClear/">MongoDB Query operator:
* $bitsAllClear</a>
* @since 2.1
*/
public Criteria bitsAllClear(int numericBitmask) {
criteria.put("$bitsAllClear", Integer.valueOf(numericBitmask));
return this;
}
/**
* Creates a criterion using the {@literal $bitsAllClear} operator.
*
* @param bitPositions positions of set bits
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllClear/">MongoDB Query operator:
* $bitsAllClear</a>
* @since 2.1
*/
public Criteria bitsAllClear(Collection<Integer> bitPositions) {
criteria.put("$bitsAllClear", bitPositions);
return this;
}
/**
* Creates a criterion using the {@literal $bitsAllSet} operator.
*
* @param numericBitmask non-negative numeric bitmask
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllSet/">MongoDB Query operator:
* $bitsAllSet</a>
* @since 2.1
*/
public Criteria bitsAllSet(int numericBitmask) {
criteria.put("$bitsAllSet", Integer.valueOf(numericBitmask));
return this;
}
/**
* Creates a criterion using the {@literal $bitsAllSet} operator.
*
* @param bitPositions positions of set bits
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllSet/">MongoDB Query operator:
* $bitsAllSet</a>
* @since 2.1
*/
public Criteria bitsAllSet(Collection<Integer> bitPositions) {
criteria.put("$bitsAllSet", bitPositions);
return this;
}
/**
* Creates a criterion using the {@literal $bitsAnyClear} operator.
*
* @param numericBitmask non-negative numeric bitmask
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnyClear/">MongoDB Query operator:
* $bitsAnyClear</a>
* @since 2.1
*/
public Criteria bitsAnyClear(int numericBitmask) {
criteria.put("$bitsAnyClear", Integer.valueOf(numericBitmask));
return this;
}
/**
* Creates a criterion using the {@literal $bitsAnyClear} operator.
*
* @param bitPositions positions of set bits
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnyClear/">MongoDB Query operator:
* $bitsAnyClear</a>
* @since 2.1
*/
public Criteria bitsAnyClear(Collection<Integer> bitPositions) {
criteria.put("$bitsAnyClear", bitPositions);
return this;
}
/**
* Creates a criterion using the {@literal $bitsAnySet} operator.
*
* @param numericBitmask non-negative numeric bitmask
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnySet/">MongoDB Query operator:
* $bitsAnySet</a>
* @since 2.1
*/
public Criteria bitsAnySet(int numericBitmask) {
criteria.put("$bitsAnySet", Integer.valueOf(numericBitmask));
return this;
}
/**
* Creates a criterion using the {@literal $bitsAnySet} operator.
*
* @param bitPositions positions of set bits
* @return
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnySet/">MongoDB Query operator:
* $bitsAnySet</a>
* @since 2.1
*/
public Criteria bitsAnySet(Collection<Integer> bitPositions) {
criteria.put("$bitsAnySet", bitPositions);
return this;
}
private Criteria registerCriteriaChainElement(Criteria criteria) {
@ -993,4 +895,324 @@ public class Criteria implements CriteriaDefinition { @@ -993,4 +895,324 @@ public class Criteria implements CriteriaDefinition {
return value instanceof GeoJson
|| (value instanceof GeoCommand && ((GeoCommand) value).getShape() instanceof GeoJson);
}
/**
* MongoDB specific <a href="https://docs.mongodb.com/manual/reference/operator/query-bitwise/">bitwise query
* operators</a> like {@code $bitsAllClear, $bitsAllSet,...} for usage with {@link Criteria#bits()} and {@link Query}.
*
* @author Christoph Strobl
* @since 2.1
* @see <a href=
* "https://docs.mongodb.com/manual/reference/operator/query-bitwise/">https://docs.mongodb.com/manual/reference/operator/query-bitwise/</a>
* @currentRead Beyond the Shadows - Brent Weeks
*/
public interface BitwiseCriteriaOperators {
/**
* Creates a criterion using {@literal $bitsAllClear} matching documents where all given bit positions are clear
* (i.e. 0).
*
* @param numericBitmask non-negative numeric bitmask.
* @return target {@link Criteria}.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllClear/">MongoDB Query operator:
* $bitsAllClear</a>
* @since 2.1
*/
Criteria allClear(int numericBitmask);
/**
* Creates a criterion using {@literal $bitsAllClear} matching documents where all given bit positions are clear
* (i.e. 0).
*
* @param bitmask string representation of a bitmask that will be converted to its base64 encoded {@link Binary}
* representation. Must not be {@literal null} nor empty.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when bitmask is {@literal null} or empty.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllClear/">MongoDB Query operator:
* $bitsAllClear</a>
* @since 2.1
*/
Criteria allClear(String bitmask);
/**
* Creates a criterion using {@literal $bitsAllClear} matching documents where all given bit positions are clear
* (i.e. 0).
*
* @param positions list of non-negative integer positions. Positions start at 0 from the least significant bit.
* Must not be {@literal null} nor contain {@literal null} elements.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when positions is {@literal null} or contains {@literal null} elements.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllClear/">MongoDB Query operator:
* $bitsAllClear</a>
* @since 2.1
*/
Criteria allClear(List<Integer> positions);
/**
* Creates a criterion using {@literal $bitsAllSet} matching documents where all given bit positions are set (i.e.
* 1).
*
* @param numericBitmask non-negative numeric bitmask.
* @return target {@link Criteria}.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllSet/">MongoDB Query operator:
* $bitsAllSet</a>
* @since 2.1
*/
Criteria allSet(int numericBitmask);
/**
* Creates a criterion using {@literal $bitsAllSet} matching documents where all given bit positions are set (i.e.
* 1).
*
* @param bitmask string representation of a bitmask that will be converted to its base64 encoded {@link Binary}
* representation. Must not be {@literal null} nor empty.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when bitmask is {@literal null} or empty.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllSet/">MongoDB Query operator:
* $bitsAllSet</a>
* @since 2.1
*/
Criteria allSet(String bitmask);
/**
* Creates a criterion using {@literal $bitsAllSet} matching documents where all given bit positions are set (i.e.
* 1).
*
* @param positions list of non-negative integer positions. Positions start at 0 from the least significant bit.
* Must not be {@literal null} nor contain {@literal null} elements.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when positions is {@literal null} or contains {@literal null} elements.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAllSet/">MongoDB Query operator:
* $bitsAllSet</a>
* @since 2.1
*/
Criteria allSet(List<Integer> positions);
/**
* Creates a criterion using {@literal $bitsAllClear} matching documents where any given bit positions are clear
* (i.e. 0).
*
* @param numericBitmask non-negative numeric bitmask.
* @return target {@link Criteria}.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnyClear/">MongoDB Query operator:
* $bitsAnyClear</a>
* @since 2.1
*/
Criteria anyClear(int numericBitmask);
/**
* Creates a criterion using {@literal $bitsAllClear} matching documents where any given bit positions are clear
* (i.e. 0).
*
* @param bitmask string representation of a bitmask that will be converted to its base64 encoded {@link Binary}
* representation. Must not be {@literal null} nor empty.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when bitmask is {@literal null} or empty.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnyClear/">MongoDB Query operator:
* $bitsAnyClear</a>
* @since 2.1
*/
Criteria anyClear(String bitmask);
/**
* Creates a criterion using {@literal $bitsAllClear} matching documents where any given bit positions are clear
* (i.e. 0).
*
* @param positions list of non-negative integer positions. Positions start at 0 from the least significant bit.
* Must not be {@literal null} nor contain {@literal null} elements.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when positions is {@literal null} or contains {@literal null} elements.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnyClear/">MongoDB Query operator:
* $bitsAnyClear</a>
* @since 2.1
*/
Criteria anyClear(List<Integer> positions);
/**
* Creates a criterion using {@literal $bitsAllSet} matching documents where any given bit positions are set (i.e.
* 1).
*
* @param numericBitmask non-negative numeric bitmask.
* @return target {@link Criteria}.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnySet/">MongoDB Query operator:
* $bitsAnySet</a>
* @since 2.1
*/
Criteria anySet(int numericBitmask);
/**
* Creates a criterion using {@literal $bitsAnySet} matching documents where any given bit positions are set (i.e.
* 1).
*
* @param bitmask string representation of a bitmask that will be converted to its base64 encoded {@link Binary}
* representation. Must not be {@literal null} nor empty.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when bitmask is {@literal null} or empty.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnySet/">MongoDB Query operator:
* $bitsAnySet</a>
* @since 2.1
*/
Criteria anySet(String bitmask);
/**
* Creates a criterion using {@literal $bitsAnySet} matching documents where any given bit positions are set (i.e.
* 1).
*
* @param positions list of non-negative integer positions. Positions start at 0 from the least significant bit.
* Must not be {@literal null} nor contain {@literal null} elements.
* @return target {@link Criteria}.
* @throws IllegalArgumentException when positions is {@literal null} or contains {@literal null} elements.
* @see <a href="https://docs.mongodb.com/manual/reference/operator/query/bitsAnySet/">MongoDB Query operator:
* $bitsAnySet</a>
* @since 2.1
*/
Criteria anySet(List<Integer> positions);
}
/**
* Default implementation of {@link BitwiseCriteriaOperators}.
*
* @author Christoph Strobl
* @currentRead Beyond the Shadows - Brent Weeks
*/
private static class BitwiseCriteriaOperatorsImpl implements BitwiseCriteriaOperators {
private final Criteria target;
BitwiseCriteriaOperatorsImpl(Criteria target) {
this.target = target;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#allClear(int)
*/
@Override
public Criteria allClear(int numericBitmask) {
return numericBitmask("$bitsAllClear", numericBitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#allClear(java.lang.String)
*/
@Override
public Criteria allClear(String bitmask) {
return stringBitmask("$bitsAllClear", bitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#allClear(java.util.List)
*/
@Override
public Criteria allClear(List<Integer> positions) {
return positions("$bitsAllClear", positions);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#allSet(int)
*/
@Override
public Criteria allSet(int numericBitmask) {
return numericBitmask("$bitsAllSet", numericBitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#allSet(java.lang.String)
*/
@Override
public Criteria allSet(String bitmask) {
return stringBitmask("$bitsAllSet", bitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#allSet(java.util.List)
*/
@Override
public Criteria allSet(List<Integer> positions) {
return positions("$bitsAllSet", positions);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#anyClear(int)
*/
@Override
public Criteria anyClear(int numericBitmask) {
return numericBitmask("$bitsAnyClear", numericBitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#anyClear(java.lang.String)
*/
@Override
public Criteria anyClear(String bitmask) {
return stringBitmask("$bitsAnyClear", bitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#anyClear(java.util.List)
*/
@Override
public Criteria anyClear(List<Integer> positions) {
return positions("$bitsAnyClear", positions);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#anySet(int)
*/
@Override
public Criteria anySet(int numericBitmask) {
return numericBitmask("$bitsAnySet", numericBitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#anySet(java.lang.String)
*/
@Override
public Criteria anySet(String bitmask) {
return stringBitmask("$bitsAnySet", bitmask);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.BitwiseCriteriaOperators#anySet(java.util.Collection)
*/
@Override
public Criteria anySet(List<Integer> positions) {
return positions("$bitsAnySet", positions);
}
private Criteria positions(String operator, List<Integer> positions) {
Assert.notNull(positions, "Positions must not be null!");
Assert.noNullElements(positions.toArray(), "Positions must not contain null values.");
target.criteria.put(operator, positions);
return target;
}
private Criteria stringBitmask(String operator, String bitmask) {
Assert.hasText(bitmask, "Bitmask must not be null!");
target.criteria.put(operator, new Binary(Base64Utils.decodeFromString(bitmask)));
return target;
}
private Criteria numericBitmask(String operator, int bitmask) {
target.criteria.put(operator, bitmask);
return target;
}
}
}

55
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -3361,61 +3361,6 @@ public class MongoTemplateTests { @@ -3361,61 +3361,6 @@ public class MongoTemplateTests {
assertThat(template.count(query(where("field").is("stark")), Sample.class)).isEqualTo(0L);
}
@Test // DATAMONGO-1808
public void testFindByBitmasks() {
DocumentWithBitmask document = new DocumentWithBitmask(0b101);
template.insert(document);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAllClear(0b010)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAllClear(Arrays.asList(1))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAllClear(0b010)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAllClear(Arrays.asList(1))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAllSet(0b101)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAllSet(Arrays.asList(0, 2))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAllSet(0b101)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAllSet(Arrays.asList(0, 2))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAnyClear(0b111)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAnyClear(Arrays.asList(0, 1, 2))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAnyClear(0b111)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAnyClear(Arrays.asList(0, 1, 2))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAnySet(0b111)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("intValue").bitsAnySet(Arrays.asList(0, 1, 2))),
DocumentWithBitmask.class)).hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAnySet(0b111)), DocumentWithBitmask.class))
.hasSize(1);
assertThat(template.find(Query.query(Criteria.where("binaryValue").bitsAnySet(Arrays.asList(0, 1, 2))),
DocumentWithBitmask.class)).hasSize(1);
}
@NoArgsConstructor
static class DocumentWithBitmask {
@Id String id;
int intValue;
byte[] binaryValue;
public DocumentWithBitmask(int value) {
this.intValue = value;
this.binaryValue = new byte[] { (byte) value };
}
}
static class TypeWithNumbers {
@Id String id;

301
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 the original author or authors.
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,268 +15,151 @@ @@ -15,268 +15,151 @@
*/
package org.springframework.data.mongodb.core.query;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Arrays;
import java.util.Collections;
import org.bson.Document;
import org.bson.types.Binary;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.Base64Utils;
import com.mongodb.MongoClient;
/**
* @author Oliver Gierke
* @author Thomas Darimont
* Integration tests for {@link Criteria} usage as part of a {@link Query}.
*
* @author Christoph Strobl
* @author Andreas Zink
*/
public class CriteriaTests {
@Test
public void testSimpleCriteria() {
Criteria c = new Criteria("name").is("Bubba");
assertEquals(Document.parse("{ \"name\" : \"Bubba\"}"), c.getCriteriaObject());
}
@Test
public void testNotEqualCriteria() {
Criteria c = new Criteria("name").ne("Bubba");
assertEquals(Document.parse("{ \"name\" : { \"$ne\" : \"Bubba\"}}"), c.getCriteriaObject());
}
@Test
public void buildsIsNullCriteriaCorrectly() {
Document reference = new Document("name", null);
Criteria criteria = new Criteria("name").is(null);
assertThat(criteria.getCriteriaObject(), is(reference));
}
@Test
public void testChainedCriteria() {
Criteria c = new Criteria("name").is("Bubba").and("age").lt(21);
assertEquals(Document.parse("{ \"name\" : \"Bubba\" , \"age\" : { \"$lt\" : 21}}"), c.getCriteriaObject());
}
@Test(expected = InvalidMongoDbApiUsageException.class)
public void testCriteriaWithMultipleConditionsForSameKey() {
Criteria c = new Criteria("name").gte("M").and("name").ne("A");
c.getCriteriaObject();
}
@Test
public void equalIfCriteriaMatches() {
Criteria left = new Criteria("name").is("Foo").and("lastname").is("Bar");
Criteria right = new Criteria("name").is("Bar").and("lastname").is("Bar");
assertThat(left, is(not(right)));
assertThat(right, is(not(left)));
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-507
public void shouldThrowExceptionWhenTryingToNegateAndOperation() {
new Criteria() //
.not() //
.andOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-507
public void shouldThrowExceptionWhenTryingToNegateOrOperation() {
new Criteria() //
.not() //
.orOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-507
public void shouldThrowExceptionWhenTryingToNegateNorOperation() {
new Criteria() //
.not() //
.norOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
}
@Test // DATAMONGO-507
public void shouldNegateFollowingSimpleExpression() {
Criteria c = Criteria.where("age").not().gt(18).and("status").is("student");
Document co = c.getCriteriaObject();
assertThat(co, is(notNullValue()));
assertThat(co, is(Document.parse("{ \"age\" : { \"$not\" : { \"$gt\" : 18}} , \"status\" : \"student\"}")));
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldReturnEmptyDocumentWhenNoCriteriaSpecified() {
Document document = new Criteria().getCriteriaObject();
assertThat(document, equalTo(new Document()));
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldUseCritieraValuesWhenNoKeyIsPresent() {
MongoOperations ops;
MongoClient client;
Document document = new Criteria().lt("foo").getCriteriaObject();
static final DocumentWithBitmask FIFTY_FOUR/*00110110*/ = new DocumentWithBitmask("1", Integer.valueOf(54),
Integer.toBinaryString(54));
static final DocumentWithBitmask TWENTY_INT/*00010100*/ = new DocumentWithBitmask("2", Integer.valueOf(20),
Integer.toBinaryString(20));
static final DocumentWithBitmask TWENTY_FLOAT/*00010100*/ = new DocumentWithBitmask("3", Float.valueOf(20),
Integer.toBinaryString(20));
static final DocumentWithBitmask ONE_HUNDRED_TWO/*01100110*/ = new DocumentWithBitmask("4",
new Binary(Base64Utils.decodeFromString("Zg==")), "01100110");
assertThat(document, equalTo(new Document().append("$lt", "foo")));
}
@Before
public void setUp() {
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldUseCritieraValuesWhenNoKeyIsPresentButMultipleCriteriasPresent() {
client = new MongoClient();
ops = new MongoTemplate(client, "criteria-tests");
Document document = new Criteria().lt("foo").gt("bar").getCriteriaObject();
ops.dropCollection(DocumentWithBitmask.class);
assertThat(document, equalTo(new Document().append("$lt", "foo").append("$gt", "bar")));
ops.insert(FIFTY_FOUR);
ops.insert(TWENTY_INT);
ops.insert(TWENTY_FLOAT);
ops.insert(ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldRespectNotWhenNoKeyPresent() {
Document document = new Criteria().lt("foo").not().getCriteriaObject();
assertThat(document, equalTo(new Document().append("$not", new Document("$lt", "foo"))));
}
@Test // DATAMONGO-1135
public void geoJsonTypesShouldBeWrappedInGeometry() {
Document document = new Criteria("foo").near(new GeoJsonPoint(100, 200)).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$near.$geometry", new GeoJsonPoint(100, 200)));
}
@Test // DATAMONGO-1135
public void legacyCoordinateTypesShouldNotBeWrappedInGeometry() {
Document document = new Criteria("foo").near(new Point(100, 200)).getCriteriaObject();
@Test // DATAMONGO-1808
public void bitsAllClearWithBitPositions() {
assertThat(document, isBsonObject().notContaining("foo.$near.$geometry"));
assertThat(ops.find(query(where("value").bits().allClear(Arrays.asList(1, 5))), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(TWENTY_INT, TWENTY_FLOAT);
}
@Test // DATAMONGO-1135
public void maxDistanceShouldBeMappedInsideNearWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").near(new GeoJsonPoint(100, 200)).maxDistance(50D).getCriteriaObject();
@Test // DATAMONGO-1808
public void bitsAllClearWithNumericBitmask() {
assertThat(document, isBsonObject().containing("foo.$near.$maxDistance", 50D));
assertThat(ops.find(query(where("value").bits().allClear(35)), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(TWENTY_INT, TWENTY_FLOAT);
}
@Test // DATAMONGO-1135
public void maxDistanceShouldBeMappedInsideNearSphereWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).maxDistance(50D).getCriteriaObject();
@Test // DATAMONGO-1808
public void bitsAllClearWithStringBitmask() {
assertThat(document, isBsonObject().containing("foo.$nearSphere.$maxDistance", 50D));
assertThat(ops.find(query(where("value").bits().allClear("ID==")), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(TWENTY_INT, TWENTY_FLOAT);
}
@Test // DATAMONGO-1110
public void minDistanceShouldBeMappedInsideNearWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").near(new GeoJsonPoint(100, 200)).minDistance(50D).getCriteriaObject();
@Test // DATAMONGO-1808
public void bitsAllSetWithBitPositions() {
assertThat(document, isBsonObject().containing("foo.$near.$minDistance", 50D));
assertThat(ops.find(query(where("value").bits().allSet(Arrays.asList(1, 5))), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR, ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1110
public void minDistanceShouldBeMappedInsideNearSphereWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).minDistance(50D).getCriteriaObject();
@Test // DATAMONGO-1808
public void bitsAllSetWithNumericBitmask() {
assertThat(document, isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
assertThat(ops.find(query(where("value").bits().allSet(50)), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR);
}
@Test // DATAMONGO-1110
public void minAndMaxDistanceShouldBeMappedInsideNearSphereWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).minDistance(50D).maxDistance(100D)
.getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
assertThat(document, isBsonObject().containing("foo.$nearSphere.$maxDistance", 100D));
}
@Test // DATAMONGO-1808
public void bitsAllSetWithStringBitmask() {
@Test(expected = IllegalArgumentException.class) // DATAMONGO-1134
public void intersectsShouldThrowExceptionWhenCalledWihtNullValue() {
new Criteria("foo").intersects(null);
assertThat(ops.find(query(where("value").bits().allSet("MC==")), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR);
}
@Test // DATAMONGO-1134
public void intersectsShouldWrapGeoJsonTypeInGeometryCorrectly() {
GeoJsonLineString lineString = new GeoJsonLineString(new Point(0, 0), new Point(10, 10));
Document document = new Criteria("foo").intersects(lineString).getCriteriaObject();
@Test // DATAMONGO-1808
public void bitsAnyClearWithBitPositions() {
assertThat(document, isBsonObject().containing("foo.$geoIntersects.$geometry", lineString));
assertThat(ops.find(query(where("value").bits().anyClear(Arrays.asList(1, 5))), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(TWENTY_INT, TWENTY_FLOAT);
}
@Test // DATAMONGO-1835
public void extractsJsonSchemaInChainCorrectly() {
MongoJsonSchema schema = MongoJsonSchema.builder().required("name").build();
Criteria critera = Criteria.where("foo").is("bar").andDocumentStructureMatches(schema);
@Test // DATAMONGO-1808
public void bitsAnyClearWithNumericBitmask() {
assertThat(critera.getCriteriaObject(), is(equalTo(new Document("foo", "bar").append("$jsonSchema",
new Document("type", "object").append("required", Collections.singletonList("name"))))));
assertThat(ops.find(query(where("value").bits().anyClear(35)), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR, TWENTY_INT, TWENTY_FLOAT, ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1835
public void extractsJsonSchemaFromFactoryMethodCorrectly() {
MongoJsonSchema schema = MongoJsonSchema.builder().required("name").build();
Criteria critera = Criteria.matchingDocumentStructure(schema);
@Test // DATAMONGO-1808
public void bitsAnyClearWithStringBitmask() {
assertThat(critera.getCriteriaObject(), is(equalTo(new Document("$jsonSchema",
new Document("type", "object").append("required", Collections.singletonList("name"))))));
assertThat(ops.find(query(where("value").bits().anyClear("MC==")), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(TWENTY_INT, TWENTY_FLOAT, ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1808
public void testBitsAllClear() {
Criteria numericBitmaskCriteria = new Criteria("field").bitsAllClear(0b101);
assertEquals(Document.parse("{ \"field\" : { \"$bitsAllClear\" : 5} }"),
numericBitmaskCriteria.getCriteriaObject());
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bitsAllClear(Arrays.asList(0, 2));
assertEquals(Document.parse("{ \"field\" : { \"$bitsAllClear\" : [ 0, 2 ]} }"),
bitPositionsBitmaskCriteria.getCriteriaObject());
public void bitsAnySetWithBitPositions() {
assertThat(ops.find(query(where("value").bits().anySet(Arrays.asList(1, 5))), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR, ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1808
public void testBitsAllSet() {
Criteria numericBitmaskCriteria = new Criteria("field").bitsAllSet(0b101);
assertEquals(Document.parse("{ \"field\" : { \"$bitsAllSet\" : 5} }"), numericBitmaskCriteria.getCriteriaObject());
public void bitsAnySetWithNumericBitmask() {
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bitsAllSet(Arrays.asList(0, 2));
assertEquals(Document.parse("{ \"field\" : { \"$bitsAllSet\" : [ 0, 2 ]} }"),
bitPositionsBitmaskCriteria.getCriteriaObject());
assertThat(ops.find(query(where("value").bits().anySet(35)), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR, ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1808
public void testBitsAnyClear() {
Criteria numericBitmaskCriteria = new Criteria("field").bitsAnyClear(0b101);
assertEquals(Document.parse("{ \"field\" : { \"$bitsAnyClear\" : 5} }"),
numericBitmaskCriteria.getCriteriaObject());
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bitsAnyClear(Arrays.asList(0, 2));
assertEquals(Document.parse("{ \"field\" : { \"$bitsAnyClear\" : [ 0, 2 ]} }"),
bitPositionsBitmaskCriteria.getCriteriaObject());
public void bitsAnySetWithStringBitmask() {
assertThat(ops.find(query(where("value").bits().anySet("MC==")), DocumentWithBitmask.class))
.containsExactlyInAnyOrder(FIFTY_FOUR, TWENTY_INT, TWENTY_FLOAT, ONE_HUNDRED_TWO);
}
@Test // DATAMONGO-1808
public void testBitsAnySet() {
Criteria numericBitmaskCriteria = new Criteria("field").bitsAnySet(0b101);
assertEquals(Document.parse("{ \"field\" : { \"$bitsAnySet\" : 5} }"), numericBitmaskCriteria.getCriteriaObject());
@Data
@EqualsAndHashCode(exclude = "value")
@AllArgsConstructor
static class DocumentWithBitmask {
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bitsAnySet(Arrays.asList(0, 2));
assertEquals(Document.parse("{ \"field\" : { \"$bitsAnySet\" : [ 0, 2 ]} }"),
bitPositionsBitmaskCriteria.getCriteriaObject());
@Id String id;
Object value;
String binaryValue;
}
}

313
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java

@ -0,0 +1,313 @@ @@ -0,0 +1,313 @@
/*
* Copyright 2010-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core.query;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
import java.util.Arrays;
import java.util.Collections;
import org.bson.Document;
import org.junit.Test;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
/**
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
* @author Andreas Zink
*/
public class CriteriaUnitTests {
@Test
public void testSimpleCriteria() {
Criteria c = new Criteria("name").is("Bubba");
assertEquals(Document.parse("{ \"name\" : \"Bubba\"}"), c.getCriteriaObject());
}
@Test
public void testNotEqualCriteria() {
Criteria c = new Criteria("name").ne("Bubba");
assertEquals(Document.parse("{ \"name\" : { \"$ne\" : \"Bubba\"}}"), c.getCriteriaObject());
}
@Test
public void buildsIsNullCriteriaCorrectly() {
Document reference = new Document("name", null);
Criteria criteria = new Criteria("name").is(null);
assertThat(criteria.getCriteriaObject(), is(reference));
}
@Test
public void testChainedCriteria() {
Criteria c = new Criteria("name").is("Bubba").and("age").lt(21);
assertEquals(Document.parse("{ \"name\" : \"Bubba\" , \"age\" : { \"$lt\" : 21}}"), c.getCriteriaObject());
}
@Test(expected = InvalidMongoDbApiUsageException.class)
public void testCriteriaWithMultipleConditionsForSameKey() {
Criteria c = new Criteria("name").gte("M").and("name").ne("A");
c.getCriteriaObject();
}
@Test
public void equalIfCriteriaMatches() {
Criteria left = new Criteria("name").is("Foo").and("lastname").is("Bar");
Criteria right = new Criteria("name").is("Bar").and("lastname").is("Bar");
assertThat(left, is(not(right)));
assertThat(right, is(not(left)));
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-507
public void shouldThrowExceptionWhenTryingToNegateAndOperation() {
new Criteria() //
.not() //
.andOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-507
public void shouldThrowExceptionWhenTryingToNegateOrOperation() {
new Criteria() //
.not() //
.orOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-507
public void shouldThrowExceptionWhenTryingToNegateNorOperation() {
new Criteria() //
.not() //
.norOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
}
@Test // DATAMONGO-507
public void shouldNegateFollowingSimpleExpression() {
Criteria c = Criteria.where("age").not().gt(18).and("status").is("student");
Document co = c.getCriteriaObject();
assertThat(co, is(notNullValue()));
assertThat(co, is(Document.parse("{ \"age\" : { \"$not\" : { \"$gt\" : 18}} , \"status\" : \"student\"}")));
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldReturnEmptyDocumentWhenNoCriteriaSpecified() {
Document document = new Criteria().getCriteriaObject();
assertThat(document, equalTo(new Document()));
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldUseCritieraValuesWhenNoKeyIsPresent() {
Document document = new Criteria().lt("foo").getCriteriaObject();
assertThat(document, equalTo(new Document().append("$lt", "foo")));
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldUseCritieraValuesWhenNoKeyIsPresentButMultipleCriteriasPresent() {
Document document = new Criteria().lt("foo").gt("bar").getCriteriaObject();
assertThat(document, equalTo(new Document().append("$lt", "foo").append("$gt", "bar")));
}
@Test // DATAMONGO-1068
public void getCriteriaObjectShouldRespectNotWhenNoKeyPresent() {
Document document = new Criteria().lt("foo").not().getCriteriaObject();
assertThat(document, equalTo(new Document().append("$not", new Document("$lt", "foo"))));
}
@Test // DATAMONGO-1135
public void geoJsonTypesShouldBeWrappedInGeometry() {
Document document = new Criteria("foo").near(new GeoJsonPoint(100, 200)).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$near.$geometry", new GeoJsonPoint(100, 200)));
}
@Test // DATAMONGO-1135
public void legacyCoordinateTypesShouldNotBeWrappedInGeometry() {
Document document = new Criteria("foo").near(new Point(100, 200)).getCriteriaObject();
assertThat(document, isBsonObject().notContaining("foo.$near.$geometry"));
}
@Test // DATAMONGO-1135
public void maxDistanceShouldBeMappedInsideNearWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").near(new GeoJsonPoint(100, 200)).maxDistance(50D).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$near.$maxDistance", 50D));
}
@Test // DATAMONGO-1135
public void maxDistanceShouldBeMappedInsideNearSphereWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).maxDistance(50D).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$nearSphere.$maxDistance", 50D));
}
@Test // DATAMONGO-1110
public void minDistanceShouldBeMappedInsideNearWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").near(new GeoJsonPoint(100, 200)).minDistance(50D).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$near.$minDistance", 50D));
}
@Test // DATAMONGO-1110
public void minDistanceShouldBeMappedInsideNearSphereWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).minDistance(50D).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
}
@Test // DATAMONGO-1110
public void minAndMaxDistanceShouldBeMappedInsideNearSphereWhenUsedAlongWithGeoJsonType() {
Document document = new Criteria("foo").nearSphere(new GeoJsonPoint(100, 200)).minDistance(50D).maxDistance(100D)
.getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$nearSphere.$minDistance", 50D));
assertThat(document, isBsonObject().containing("foo.$nearSphere.$maxDistance", 100D));
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-1134
public void intersectsShouldThrowExceptionWhenCalledWihtNullValue() {
new Criteria("foo").intersects(null);
}
@Test // DATAMONGO-1134
public void intersectsShouldWrapGeoJsonTypeInGeometryCorrectly() {
GeoJsonLineString lineString = new GeoJsonLineString(new Point(0, 0), new Point(10, 10));
Document document = new Criteria("foo").intersects(lineString).getCriteriaObject();
assertThat(document, isBsonObject().containing("foo.$geoIntersects.$geometry", lineString));
}
@Test // DATAMONGO-1835
public void extractsJsonSchemaInChainCorrectly() {
MongoJsonSchema schema = MongoJsonSchema.builder().required("name").build();
Criteria criteria = Criteria.where("foo").is("bar").andDocumentStructureMatches(schema);
assertThat(criteria.getCriteriaObject(), is(equalTo(new Document("foo", "bar").append("$jsonSchema",
new Document("type", "object").append("required", Collections.singletonList("name"))))));
}
@Test // DATAMONGO-1835
public void extractsJsonSchemaFromFactoryMethodCorrectly() {
MongoJsonSchema schema = MongoJsonSchema.builder().required("name").build();
Criteria criteria = Criteria.matchingDocumentStructure(schema);
assertThat(criteria.getCriteriaObject(), is(equalTo(new Document("$jsonSchema",
new Document("type", "object").append("required", Collections.singletonList("name"))))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAllClearWithIntBitmaskCorrectly() {
Criteria numericBitmaskCriteria = new Criteria("field").bits().allClear(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAllClear\" : 5} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAllClearWithPositionListCorrectly() {
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bits().allClear(Arrays.asList(0, 2));
assertThat(bitPositionsBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAllClear\" : [ 0, 2 ]} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAllSetWithIntBitmaskCorrectly() {
Criteria numericBitmaskCriteria = new Criteria("field").bits().allSet(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAllSet\" : 5} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAllSetWithPositionListCorrectly() {
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bits().allSet(Arrays.asList(0, 2));
assertThat(bitPositionsBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAllSet\" : [ 0, 2 ]} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAnyClearWithIntBitmaskCorrectly() {
Criteria numericBitmaskCriteria = new Criteria("field").bits().anyClear(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAnyClear\" : 5} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAnyClearWithPositionListCorrectly() {
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bits().anyClear(Arrays.asList(0, 2));
assertThat(bitPositionsBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAnyClear\" : [ 0, 2 ]} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAnySetWithIntBitmaskCorrectly() {
Criteria numericBitmaskCriteria = new Criteria("field").bits().anySet(0b101);
assertThat(numericBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAnySet\" : 5} }"))));
}
@Test // DATAMONGO-1808
public void shouldAppendBitsAnySetWithPositionListCorrectly() {
Criteria bitPositionsBitmaskCriteria = new Criteria("field").bits().anySet(Arrays.asList(0, 2));
assertThat(bitPositionsBitmaskCriteria.getCriteriaObject(),
is(equalTo(Document.parse("{ \"field\" : { \"$bitsAnySet\" : [ 0, 2 ]} }"))));
}
}

1
src/main/asciidoc/reference/mongodb.adoc

@ -1073,6 +1073,7 @@ As you can see most methods return the `Criteria` object to provide a fluent sty @@ -1073,6 +1073,7 @@ As you can see most methods return the `Criteria` object to provide a fluent sty
* `Criteria` *size* `(int s)` Creates a criterion using the `$size` operator
* `Criteria` *type* `(int t)` Creates a criterion using the `$type` operator
* `Criteria` *matchingDocumentStructure* `(MongoJsonSchema schema)` Creates a criterion using the `$jsonSchema` operator for <<mongo.jsonSchema,JSON schema criteria>>. `$jsonSchema` can only be applied on the top level of a query and not property specific. Use the `properties` attribute of the schema to match against nested fields.
* `Criteria` *bits()* is the gateway to https://docs.mongodb.com/manual/reference/operator/query-bitwise/[MongoDB bitwise query operators] like `$bitsAllClear`.
There are also methods on the Criteria class for geospatial queries. Here is a listing but look at the section on <<mongo.geospatial,GeoSpatial Queries>> to see them in action.

Loading…
Cancel
Save