diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/annotations/UseDialect.java b/redis-om-spring/src/main/java/com/redis/om/spring/annotations/UseDialect.java index 1defded31..10f2ab355 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/annotations/UseDialect.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/annotations/UseDialect.java @@ -8,5 +8,5 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface UseDialect { - Dialect dialect() default Dialect.ONE; + Dialect dialect() default Dialect.TWO; } diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/repository/query/RediSearchQuery.java b/redis-om-spring/src/main/java/com/redis/om/spring/repository/query/RediSearchQuery.java index c5c4bf5c2..7b1f6d0a2 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/repository/query/RediSearchQuery.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/repository/query/RediSearchQuery.java @@ -87,7 +87,7 @@ public class RediSearchQuery implements RepositoryQuery { private Boolean aggregationVerbatim; private Gson gson; private boolean isNullParamQuery; - private Dialect dialect = Dialect.ONE; + private Dialect dialect = Dialect.TWO; @SuppressWarnings("unchecked") public RediSearchQuery(// @@ -416,6 +416,7 @@ private Object executeQuery(Object[] parameters) { boolean excludeNullParams = !isNullParamQuery; String preparedQuery = prepareQuery(parameters, excludeNullParams); Query query = new Query(preparedQuery); + query.dialect(2); ReturnedType returnedType = processor.getReturnedType(); diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java b/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java index c51e25b24..f0d755c26 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/repository/support/SimpleRedisDocumentRepository.java @@ -6,6 +6,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.redis.om.spring.RedisOMProperties; +import com.redis.om.spring.annotations.Dialect; import com.redis.om.spring.audit.EntityAuditor; import com.redis.om.spring.convert.MappingRedisOMConverter; import com.redis.om.spring.id.IdentifierFilter; @@ -424,12 +425,12 @@ public Optional findOne(Example example) { @Override public Iterable findAll(Example example) { - return entityStream.of(example.getProbeType()).filter(example).collect(Collectors.toList()); + return entityStream.of(example.getProbeType()).dialect(Dialect.TWO.getValue()).filter(example).collect(Collectors.toList()); } @Override public Iterable findAll(Example example, Sort sort) { - return entityStream.of(example.getProbeType()).filter(example).sorted(sort).collect(Collectors.toList()); + return entityStream.of(example.getProbeType()).dialect(Dialect.TWO.getValue()).filter(example).sorted(sort).collect(Collectors.toList()); } @Override @@ -437,7 +438,7 @@ public Page findAll(Example example, Pageable pageable) { SearchStream stream = entityStream.of(example.getProbeType()); var offset = pageable.getPageNumber() * pageable.getPageSize(); var limit = pageable.getPageSize(); - Page page = stream.filter(example).loadAll().limit(limit, Math.toIntExact(offset)) + Page page = stream.filter(example).dialect(Dialect.TWO.getValue()).loadAll().limit(limit, Math.toIntExact(offset)) .toList(pageable, stream.getEntityClass()); return page; diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationPage.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationPage.java index 6c7a50775..dc71c80bd 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationPage.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationPage.java @@ -1,6 +1,7 @@ package com.redis.om.spring.search.stream; import com.google.gson.Gson; +import com.redis.om.spring.annotations.Dialect; import com.redis.om.spring.convert.MappingRedisOMConverter; import com.redis.om.spring.ops.search.SearchOperations; import com.redis.om.spring.util.ObjectUtils; @@ -118,6 +119,7 @@ public long getTotalElements() { String baseQuery = aggregationStream.backingQuery(); Query countQuery = (baseQuery.isBlank()) ? new Query() : new Query(baseQuery); countQuery.setNoContent(); + countQuery.dialect(Dialect.TWO.getValue()); for (Order order : pageable.getSort()) { countQuery.setSortBy(order.getProperty(), order.isAscending()); } diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationStreamImpl.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationStreamImpl.java index 03461a82d..acb5c00ef 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationStreamImpl.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/AggregationStreamImpl.java @@ -1,6 +1,7 @@ package com.redis.om.spring.search.stream; import com.google.gson.Gson; +import com.redis.om.spring.annotations.Dialect; import com.redis.om.spring.annotations.Document; import com.redis.om.spring.annotations.ReducerFunction; import com.redis.om.spring.convert.MappingRedisOMConverter; @@ -42,6 +43,7 @@ public AggregationStreamImpl(String searchIndex, RedisModulesOperations this.entityClass = entityClass; search = modulesOperations.opsForSearch(searchIndex); aggregation = new AggregationBuilder(query); + aggregation.dialect(Dialect.TWO.getValue()); isDocument = entityClass.isAnnotationPresent(Document.class); this.query = query; this.gson = gson; diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/ExampleToNodeConverter.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/ExampleToNodeConverter.java index 3d69eacc9..37d217d11 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/ExampleToNodeConverter.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/ExampleToNodeConverter.java @@ -86,9 +86,9 @@ public Node processExample(Example example, Node rootNode) { } } else { if (matchingAll) { - rootNode = QueryBuilders.intersect(rootNode).add(fieldName, "{" + QueryUtils.escape(value) + "}"); + rootNode = QueryBuilders.intersect(rootNode).add(fieldName, "{\"" + value + "\"}"); } else { - rootNode = QueryBuilders.union(rootNode).add(fieldName, "{" + QueryUtils.escape(value) + "}"); + rootNode = QueryBuilders.union(rootNode).add(fieldName, "{\"" + value + "\"}"); } } } diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/RedisFluentQueryByExample.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/RedisFluentQueryByExample.java index b7521607a..fc4d2d425 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/RedisFluentQueryByExample.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/RedisFluentQueryByExample.java @@ -1,5 +1,6 @@ package com.redis.om.spring.search.stream; +import com.redis.om.spring.annotations.Dialect; import com.redis.om.spring.metamodel.MetamodelField; import com.redis.om.spring.metamodel.MetamodelUtils; import com.redis.om.spring.ops.search.SearchOperations; @@ -91,6 +92,7 @@ public RedisFluentQueryByExample( // this.searchStream = entityStream.of(resultType); this.projectionFactory = new SpelAwareProxyProjectionFactory(); this.mappingContext = mappingContext; + searchStream.dialect(Dialect.TWO.getValue()); searchStream.filter((Example)example); } @@ -151,6 +153,7 @@ public Page page(Pageable pageable) { long count = -1; if (!searchStream.backingQuery().isBlank()) { Query query = new Query(searchStream.backingQuery()); + query.dialect(Dialect.TWO.getValue()); query.limit(0, 0); SearchResult searchResult = searchOps.search(query); diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/SearchStreamImpl.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/SearchStreamImpl.java index c0d77cc33..f89721f44 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/SearchStreamImpl.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/SearchStreamImpl.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.redis.om.spring.annotations.Dialect; import com.redis.om.spring.annotations.Document; import com.redis.om.spring.convert.MappingRedisOMConverter; import com.redis.om.spring.indexing.RediSearchIndexer; @@ -78,7 +79,7 @@ public class SearchStreamImpl implements SearchStream { private Runnable closeHandler; private Stream resolvedStream; private KNNPredicate knnPredicate; - private int dialect = 1; + private int dialect = Dialect.TWO.getValue(); private SummarizeParams summarizeParams; private Pair highlightTags; private boolean isQBE = false; @@ -357,6 +358,7 @@ public long count() { if (!rootNode.toString().isBlank()) { Query query = new Query(rootNode.toString()); query.limit(0, 0); + query.dialect(Dialect.TWO.getValue()); SearchResult searchResult = search.search(query); resolvedStream = Stream.empty(); @@ -463,13 +465,14 @@ Query prepareQuery() { if (knnPredicate != null) { query = new Query(knnPredicate.apply(rootNode).toString()); + query.dialect(Dialect.TWO.getValue()); query.addParam(knnPredicate.getBlobAttributeName(), knnPredicate.getBlobAttribute() != null ? knnPredicate.getBlobAttribute() : floatArrayToByteArray(knnPredicate.getDoublesAttribute())); query.addParam("K", knnPredicate.getK()); - query.dialect(2); } else { query = (rootNode.toString().isBlank()) ? new Query() : new Query(rootNode.toString()); + query.dialect(Dialect.TWO.getValue()); query.dialect(dialect); } diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/EqualPredicate.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/EqualPredicate.java index 08ae400e7..b6cc21850 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/EqualPredicate.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/EqualPredicate.java @@ -14,7 +14,7 @@ public class EqualPredicate extends BaseAbstractPredicate { public EqualPredicate(SearchFieldAccessor field, T value) { super(field); - this.value = QueryUtils.escape(value); + this.value = value; } public T getValue() { @@ -29,12 +29,12 @@ public Node apply(Node root) { Iterable values = (Iterable) getValue(); QueryNode and = QueryBuilders.intersect(); for (Object v : values) { - and.add(getSearchAlias(), "{" + v.toString() + "}"); + and.add(getSearchAlias(), "{\"" + v.toString() + "\"}"); } return QueryBuilders.intersect(root, and); } else { - return QueryBuilders.intersect(root).add(getSearchAlias(), "{" + value.toString() + "}"); + return QueryBuilders.intersect(root).add(getSearchAlias(), "{\"" + value.toString() + "\"}"); } } -} +} \ No newline at end of file diff --git a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/NotEqualPredicate.java b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/NotEqualPredicate.java index 6fee44cea..e5acf6085 100644 --- a/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/NotEqualPredicate.java +++ b/redis-om-spring/src/main/java/com/redis/om/spring/search/stream/predicates/tag/NotEqualPredicate.java @@ -19,7 +19,7 @@ public class NotEqualPredicate extends BaseAbstractPredicate { public NotEqualPredicate(SearchFieldAccessor field, T value) { super(field); - this.value = QueryUtils.escape(value); + this.value = value; } public NotEqualPredicate(SearchFieldAccessor field, List list) { @@ -38,7 +38,7 @@ public Node apply(Node root) { QueryNode and = QueryBuilders.intersect(); StreamSupport.stream(getValues().spliterator(), false) // - .map(v -> Values.value("{" + v.toString() + "}")) + .map(v -> Values.value("{\"" + v.toString() + "\"}")) .forEach(val -> and.add(QueryBuilders.disjunct(getSearchAlias(), val))); return QueryBuilders.intersect(root, and); diff --git a/tests/src/test/java/com/redis/om/spring/search/stream/EntityStreamDocumentQBEAdvancedTest.java b/tests/src/test/java/com/redis/om/spring/search/stream/EntityStreamDocumentQBEAdvancedTest.java index 11736bc3a..165a12950 100644 --- a/tests/src/test/java/com/redis/om/spring/search/stream/EntityStreamDocumentQBEAdvancedTest.java +++ b/tests/src/test/java/com/redis/om/spring/search/stream/EntityStreamDocumentQBEAdvancedTest.java @@ -38,7 +38,7 @@ void loadTestData() { // Data from the screenshot entities.add(createDunnageEntity("TMMFV", "T423", "F3483", "CTCI", "THERMOFORME", "NO", 0, 0f, "EUR", null, null, null)); entities.add(createDunnageEntity("TMMFV", "F375", "F2413", "PPO", "CORREX + EPP", "1150X350X202", 750, 36.71f, "EUR", null, null, null)); - entities.add(createDunnageEntity("TMMFV", "C035", "F1503", "JAMES LEIGH", "FOAM", "WHITE FOAM", 690, 14.1f, "GBP", null, null, null)); + entities.add(createDunnageEntity("TMMFV", "C035", "F1-503", "JAMES LEIGH", "FOAM", "WHITE FOAM", 690, 14.1f, "GBP", null, null, null)); entities.add(createDunnageEntity("TMMFV", "F519", "F3090", "CARPENTER", "FOAM", "NO", 100, 0f, "EURO", null, null, null)); entities.add(createDunnageEntity("TMMFV", "J066", "20711", "FUJITSU TEN", "CARDBOARD DUNNAGE", "SPEAKER ASSY, RADIO", 100, 1f, "EURO", null, null, null)); entities.add(createDunnageEntity("TMMFV", "S119", "F2168", "KAYSERSBERG", "TEXT EFFITEK+EVOLON", "540X340X290", 400, 25.56f, "EUR", null, null, null)); @@ -226,6 +226,30 @@ void testSearchWithExactTextValue() { assertThat(results).extracting("dunnageCode").containsExactly("F375"); } + @Test + void testSearchWithExactTagValue() { + DunnageEntity template = DunnageEntity.builder() + .dunnageSuppcode("F1-503") + .build(); + + ExampleMatcher matcher = ExampleMatcher.matching() + .withStringMatcher(StringMatcher.EXACT) + .withIgnoreCase() + .withIgnoreNullValues(); + + Example example = Example.of(template, matcher); + + // Using entity stream + List results = entityStream.of(DunnageEntity.class) + .dialect(2) + .filter(example) + .collect(Collectors.toList()); + + // Should find entries with "FOAM" in description field despite case difference + assertThat(results).hasSize(1); + assertThat(results).extracting("dunnageCode").containsExactly("C035"); + } + private DunnageEntity createDunnageEntity(String plant, String dunnageCode, String dunnageSuppcode, String dunnageSupplier, String material, String description, Integer weight, Float unitCost, String currency,