Skip to content

Commit

Permalink
Fix $nin query with array of documents #215
Browse files Browse the repository at this point in the history
  • Loading branch information
bwaldvogel committed Jun 1, 2023
1 parent 39282b9 commit 73b7dff
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,17 @@ private boolean checkMatch(Object queryValue, List<String> keys, Object value) {
return checkMatchesValue(queryValue, value);
}

// handle $all
if (queryValue instanceof Document && ((Document) queryValue).containsKey(QueryOperator.ALL.getValue())) {
// clone first
queryValue = ((Document) queryValue).clone();
Object allQuery = ((Document) queryValue).remove(QueryOperator.ALL.getValue());
if (!checkMatchesAllDocuments(allQuery, keys, value)) {
return false;
if (queryValue instanceof Document) {
Document query = (Document) queryValue;
if (query.containsKey(QueryOperator.ALL.getValue())) {
Object allQuery = query.get(QueryOperator.ALL.getValue());
return checkMatchesAllDocuments(allQuery, keys, value);
}
if (query.containsKey(QueryOperator.NOT_IN.getValue())) {
Object notInQueryValue = query.get(QueryOperator.NOT_IN.getValue());
Document inQuery = new Document(QueryOperator.IN.getValue(), notInQueryValue);
return !checkMatchesAnyDocument(inQuery, keys, value);
}
// continue matching the remainder of queryValue
}

return checkMatchesAnyDocument(queryValue, keys, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import static de.bwaldvogel.mongo.backend.DocumentBuilder.mod;
import static de.bwaldvogel.mongo.backend.DocumentBuilder.nor;
import static de.bwaldvogel.mongo.backend.DocumentBuilder.not;
import static de.bwaldvogel.mongo.backend.DocumentBuilder.notIn;
import static de.bwaldvogel.mongo.backend.DocumentBuilder.or;
import static de.bwaldvogel.mongo.backend.DocumentBuilder.regex;
import static de.bwaldvogel.mongo.backend.DocumentBuilder.size;
Expand Down Expand Up @@ -505,45 +504,6 @@ void testMatchesNot() throws Exception {
assertThat(matcher.matches(document, query)).isTrue();
}

/**
* Test case for https://github.com/bwaldvogel/mongo-java-server/issues/7
*/
@Test
void testMatchesNotIn() throws Exception {
Document query1 = map("map.key2", notIn("value 2.2"));
Document query2 = map("map.key2", not(in("value 2.2")));
Document query3 = map("map.key2", not(notIn("value 2.2")));
Document query4 = map("map.key2", not(not(in("value 2.2"))));

Document document1 = json("code: 'c1', map: {key1: 'value 1.1', key2: ['value 2.1']}");
Document document2 = json("code: 'c1', map: {key1: 'value 1.2', key2: ['value 2.2']}");
Document document3 = json("code: 'c1', map: {key1: 'value 2.1', key2: ['value 2.1']}");

assertThat(matcher.matches(document1, query1)).isTrue();
assertThat(matcher.matches(document2, query1)).isFalse();
assertThat(matcher.matches(document3, query1)).isTrue();

assertThat(matcher.matches(document1, query2)).isTrue();
assertThat(matcher.matches(document2, query2)).isFalse();
assertThat(matcher.matches(document3, query2)).isTrue();

assertThat(matcher.matches(document1, query3)).isFalse();
assertThat(matcher.matches(document2, query3)).isTrue();
assertThat(matcher.matches(document3, query3)).isFalse();

assertThat(matcher.matches(document1, query4)).isFalse();
assertThat(matcher.matches(document2, query4)).isTrue();
assertThat(matcher.matches(document3, query4)).isFalse();

assertThat(matcher.matches(json("values: [1, 2, 3]"), json("values: {$nin: []}"))).isTrue();
assertThat(matcher.matches(json("values: null"), json("values: {$nin: []}"))).isTrue();
assertThat(matcher.matches(json(""), json("values: {$nin: []}"))).isTrue();
assertThat(matcher.matches(json(""), json("values: {$nin: [1]}"))).isTrue();
assertThat(matcher.matches(json(""), json("values: {$nin: [1, 2]}"))).isTrue();
assertThat(matcher.matches(json("values: null"), json("values: {$nin: [null]}"))).isFalse();
assertThat(matcher.matches(json(""), json("values: {$nin: [null]}"))).isFalse();
}

@Test
void testMatchesNotSize() throws Exception {
assertThat(matcher.matches(json("a: [1, 2, 3]"), json("a: {$not: {$size: 3}}"))).isFalse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2296,6 +2296,53 @@ public void testAndQueryWithAllAndNin() throws Exception {
.containsExactly(json("_id: 2, tags: ['A', 'D']"));
}

// https://github.com/bwaldvogel/mongo-java-server/issues/215
@Test
void testMatchesNinFieldInArray() throws Exception {
collection.insertOne(json("_id: 1, tags: [{'value': 'A'}, {'value': 'D'}]"));
collection.insertOne(json("_id: 2, tags: [{'value': 'A'}, {'value': 'B'}]"));
collection.insertOne(json("_id: 3, tags: [{'value': 'A'}, {'value': 'C'}]"));

assertThat(collection.find(json("'tags.value': {$nin: ['B', 'C']}")))
.containsExactly(json("_id: 1, tags: [{'value': 'A'}, {'value': 'D'}]"));
}

// https://github.com/bwaldvogel/mongo-java-server/issues/7
@Test
void testMatchesNotIn() throws Exception {
Document document1 = json("_id: 1, code: 'c1', map: {key1: 'value 1.1', key2: ['value 2.1']}");
Document document2 = json("_id: 2, code: 'c1', map: {key1: 'value 1.2', key2: ['value 2.2']}");
Document document3 = json("_id: 3, code: 'c1', map: {key1: 'value 2.1', key2: ['value 2.1']}");
Document document4 = json("_id: 4, values: [1, 2, 3]");
Document document5 = json("_id: 5, values: null");

collection.insertMany(List.of(document1, document2, document3, document4, document5));

assertThat(collection.find(json("'map.key2': {$nin: ['value 2.2']}")))
.containsExactly(document1, document3, document4, document5);

assertThat(collection.find(json("'map.key2': {$not: {$in: ['value 2.2']}}")))
.containsExactly(document1, document3, document4, document5);

assertThat(collection.find(json("'map.key2': {$not: {$nin: ['value 2.2']}}")))
.containsExactly(document2);

assertThat(collection.find(json("'map.key2': {$not: {$not: {$in: ['value 2.2']}}}")))
.containsExactly(document2);

assertThat(collection.find(json("values: {$nin: []}")))
.containsExactly(document1, document2, document3, document4, document5);

assertThat(collection.find(json("values: {$nin: [1]}")))
.containsExactly(document1, document2, document3, document5);

assertThat(collection.find(json("values: {$nin: [1, 2]}")))
.containsExactly(document1, document2, document3, document5);

assertThat(collection.find(json("values: {$nin: [null]}")))
.containsExactly(document4);
}

// https://github.com/bwaldvogel/mongo-java-server/issues/96
@Test
public void testAndQueryWithAllAndSize() throws Exception {
Expand Down

0 comments on commit 73b7dff

Please sign in to comment.