Skip to content

Commit ddb3ef2

Browse files
authored
Merge pull request #469 from weaviate/v6-contains_none-not
v6: Support ContainsNone and Not operators
2 parents 2cea539 + c768ad4 commit ddb3ef2

19 files changed

Lines changed: 29084 additions & 10424 deletions

src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private enum Operator {
1313
// Logical operators
1414
AND("And", WeaviateProtoBase.Filters.Operator.OPERATOR_AND),
1515
OR("Or", WeaviateProtoBase.Filters.Operator.OPERATOR_OR),
16+
NOT("Noe", WeaviateProtoBase.Filters.Operator.OPERATOR_NOT),
1617

1718
// Comparison operators
1819
EQUAL("Equal", WeaviateProtoBase.Filters.Operator.OPERATOR_EQUAL),
@@ -24,6 +25,7 @@ private enum Operator {
2425
LIKE("Like", WeaviateProtoBase.Filters.Operator.OPERATOR_LIKE),
2526
CONTAINS_ANY("ContainsAny", WeaviateProtoBase.Filters.Operator.OPERATOR_CONTAINS_ANY),
2627
CONTAINS_ALL("ContainsAll", WeaviateProtoBase.Filters.Operator.OPERATOR_CONTAINS_ALL),
28+
CONTAINS_NONE("ContainsNone", WeaviateProtoBase.Filters.Operator.OPERATOR_CONTAINS_NONE),
2729
WITHIN_GEO_RANGE("WithinGeoRange", WeaviateProtoBase.Filters.Operator.OPERATOR_WITHIN_GEO_RANGE);
2830

2931
/** String representation for better debug logs. */
@@ -62,35 +64,47 @@ private Where(Operator operator, List<WhereOperand> operands) {
6264

6365
@Override
6466
public boolean isEmpty() {
65-
// Guard against Where.and(Where.or(), Where.and()) situation.
67+
// Guard against Where.and(Where.or(), Where.and(), Where.not()) situation.
6668
return operands.isEmpty()
67-
|| operands.stream().allMatch(operator -> operator.isEmpty());
69+
|| operands.stream().allMatch(operator -> operator == null | operator.isEmpty());
6870
}
6971

7072
@Override
7173
public String toString() {
74+
if (operator == Operator.NOT) {
75+
return "%s %s".formatted(operator, operands.get(0));
76+
}
7277
var operandStrings = operands.stream().map(Object::toString).toList();
7378
return "Where(" + String.join(" " + operator.toString() + " ", operandStrings) + ")";
7479
}
7580

7681
// Logical operators return a complete operand.
7782
// --------------------------------------------------------------------------
78-
public static Where and(WhereOperand... operands) {
83+
public static Where and(final WhereOperand... operands) {
7984
return new Where(Operator.AND, operands);
8085
}
8186

82-
public static Where and(List<WhereOperand> operands) {
87+
public static Where and(final List<WhereOperand> operands) {
8388
return new Where(Operator.AND, operands);
8489
}
8590

86-
public static Where or(WhereOperand... operands) {
91+
public static Where or(final WhereOperand... operands) {
8792
return new Where(Operator.OR, operands);
8893
}
8994

90-
public static Where or(List<WhereOperand> operands) {
95+
public static Where or(final List<WhereOperand> operands) {
9196
return new Where(Operator.OR, operands);
9297
}
9398

99+
public static Where not(final WhereOperand operand) {
100+
return new Where(Operator.NOT, operand);
101+
}
102+
103+
/** Negate this expression. */
104+
public Where not() {
105+
return not(this);
106+
}
107+
94108
// Comparison operators return fluid builder.
95109
// --------------------------------------------------------------------------
96110

@@ -463,6 +477,32 @@ public Where containsAll(OffsetDateTime... values) {
463477
return new Where(Operator.CONTAINS_ALL, left, new DateArrayOperand(values));
464478
}
465479

480+
// ContainsNone
481+
// ------------------------------------------------------------------------
482+
public Where containsNone(String value) {
483+
return new Where(Operator.CONTAINS_NONE, left, new TextOperand(value));
484+
}
485+
486+
public Where containsNone(String... values) {
487+
return new Where(Operator.CONTAINS_NONE, left, new TextArrayOperand(values));
488+
}
489+
490+
public Where containsNone(Boolean... values) {
491+
return new Where(Operator.CONTAINS_NONE, left, new BooleanArrayOperand(values));
492+
}
493+
494+
public Where containsNone(Long... values) {
495+
return new Where(Operator.CONTAINS_NONE, left, new IntegerArrayOperand(values));
496+
}
497+
498+
public Where containsNone(Double... values) {
499+
return new Where(Operator.CONTAINS_NONE, left, new NumberArrayOperand(values));
500+
}
501+
502+
public Where containsNone(OffsetDateTime... values) {
503+
return new Where(Operator.CONTAINS_NONE, left, new DateArrayOperand(values));
504+
}
505+
466506
// WithinGeoRange
467507
// ------------------------------------------------------------------------
468508
public Where withinGeoRange(float lat, float lon, float maxDistance) {
@@ -475,25 +515,19 @@ public void appendTo(WeaviateProtoBase.Filters.Builder where) {
475515
if (isEmpty()) {
476516
return;
477517
}
478-
switch (operands.size()) {
479-
case 0:
480-
return;
481-
case 1: // no need for operator
482-
operands.get(0).appendTo(where);
483-
return;
484-
default:
485-
if (operator.equals(Operator.AND) || operator.equals(Operator.OR)) {
486-
operands.forEach(op -> {
487-
Filters.Builder nested = Filters.newBuilder();
488-
op.appendTo(nested);
489-
where.addFilters(nested);
490-
});
491-
} else {
492-
// Comparison operators: eq, gt, lt, like, etc.
493-
operands.forEach(op -> op.appendTo(where));
494-
}
495-
}
518+
496519
operator.appendTo(where);
520+
521+
if (operator == Operator.AND || operator == Operator.OR || operator == Operator.NOT) {
522+
operands.forEach(op -> {
523+
var nested = Filters.newBuilder();
524+
op.appendTo(nested);
525+
where.addFilters(nested);
526+
});
527+
} else {
528+
// Comparison operators: eq, gt, lt, like, etc.
529+
operands.forEach(op -> op.appendTo(where));
530+
}
497531
}
498532

499533
@SuppressWarnings("unchecked")
@@ -522,13 +556,13 @@ static WhereOperand fromObject(Object value) {
522556
return new NumberArrayOperand(dblarr);
523557
} else if (value instanceof OffsetDateTime[] datearr) {
524558
return new DateArrayOperand(datearr);
525-
} else if (value instanceof List) {
526-
if (((List<?>) value).isEmpty()) {
559+
} else if (value instanceof List<?> list) {
560+
if (list.isEmpty()) {
527561
throw new IllegalArgumentException(
528562
"Filter with non-reifiable type (List<T>) cannot be empty, use an array instead");
529563
}
530564

531-
Object first = ((List<?>) value).get(0);
565+
Object first = list.get(0);
532566
if (first instanceof String) {
533567
return new TextArrayOperand((List<String>) value);
534568
} else if (first instanceof Boolean) {

0 commit comments

Comments
 (0)