Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.redis.om.spring.metamodel.indexed.NumericField;
import com.redis.om.spring.ops.search.SearchOperations;
import com.redis.om.spring.search.stream.predicates.SearchFieldPredicate;
import com.redis.om.spring.tuple.Pair;
import com.redis.om.spring.tuple.Tuple;
import com.redis.om.spring.tuple.Tuples;
import com.redis.om.spring.util.ObjectUtils;
Expand Down Expand Up @@ -452,4 +453,24 @@ public String backingQuery() {
return entitySearchStream.backingQuery();
}

@Override
public <R> SearchStream<T> summarize(Function<? super T, ? extends R> field) {
throw new UnsupportedOperationException("summarize is not supported on a ReturnFieldSearchStream");
}

@Override
public <R> SearchStream<T> summarize(Function<? super T, ? extends R> field, SummarizeParams params) {
throw new UnsupportedOperationException("summarize is not supported on a ReturnFieldSearchStream");
}

@Override
public <R> SearchStream<T> highlight(Function<? super T, ? extends R> field) {
throw new UnsupportedOperationException("highlight is not supported on a ReturnFieldSearchStream");
}

@Override
public <R> SearchStream<T> highlight(Function<? super T, ? extends R> field, Pair<String,String> tags) {
throw new UnsupportedOperationException("highlight is not supported on a ReturnFieldSearchStream");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.redis.om.spring.metamodel.indexed.NumericField;
import com.redis.om.spring.ops.search.SearchOperations;
import com.redis.om.spring.search.stream.predicates.SearchFieldPredicate;
import com.redis.om.spring.tuple.Pair;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
Expand All @@ -14,6 +15,7 @@
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.*;
import java.util.stream.*;

Expand Down Expand Up @@ -119,4 +121,11 @@ public interface SearchStream<E> extends BaseStream<E, SearchStream<E>> {
<R> SearchStream<E> project(MetamodelField<? super E, ? extends R> ...field);

String backingQuery();

<R> SearchStream<E> summarize(Function<? super E, ? extends R> field);

<R> SearchStream<E> summarize(Function<? super E, ? extends R> field, SummarizeParams params);

<R> SearchStream<E> highlight(Function<? super E, ? extends R> field);
<R> SearchStream<E> highlight(Function<? super E, ? extends R> field, Pair<String,String> tags);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.redis.core.convert.ReferenceResolverImpl;
import redis.clients.jedis.search.Query;
import redis.clients.jedis.search.Query.HighlightTags;
import redis.clients.jedis.search.SearchResult;
import redis.clients.jedis.search.aggr.AggregationResult;
import redis.clients.jedis.search.aggr.SortedField;
Expand Down Expand Up @@ -75,6 +76,12 @@ public class SearchStreamImpl<E> implements SearchStream<E> {

private final List<MetamodelField<E, ?>> projections = new ArrayList<>();

private final List<MetamodelField<E, ?>> summaryFields = new ArrayList<>();
private SummarizeParams summarizeParams;
private final List<MetamodelField<E, ?>> highlightFields = new ArrayList<>();

private Pair<String,String> highlightTags;

private final ExampleToNodeConverter<E> exampleToNodeConverter;

public SearchStreamImpl(Class<E> entityClass, RedisModulesOperations<String> modulesOperations, GsonBuilder gsonBuilder,
Expand Down Expand Up @@ -426,6 +433,36 @@ Query prepareQuery() {
query.setSortBy(sortField.getField(), sortField.getOrder().equals("ASC"));
}

if (!summaryFields.isEmpty()) {
var fields = summaryFields.stream() //
.map(foi -> ObjectUtils.isCollection(foi.getTargetClass()) ? "$." + foi.getSearchAlias() : foi.getSearchAlias())
.collect(toCollection(ArrayList::new));

if (summarizeParams == null) {
query.summarizeFields(fields.toArray(String[]::new));
} else {
query.summarizeFields( //
summarizeParams.getFragSize(), //
summarizeParams.getFragsNum(), //
summarizeParams.getSeparator(), //
fields.toArray(String[]::new) //
);
}
}

if (!highlightFields.isEmpty()) {
var fields = highlightFields.stream() //
.map(foi -> ObjectUtils.isCollection(foi.getTargetClass()) ? "$." + foi.getSearchAlias() : foi.getSearchAlias())
.collect(toCollection(ArrayList::new));

if (highlightTags == null) {
query.highlightFields(fields.toArray(String[]::new));
} else {
HighlightTags tags = new HighlightTags(highlightTags.getFirst(),highlightTags.getSecond());
query.highlightFields(tags, fields.toArray(String[]::new));
}
}

if (onlyIds) {
query.returnFields(idField.getName());
} else if (!projections.isEmpty()) {
Expand Down Expand Up @@ -652,6 +689,58 @@ public String backingQuery() {
return rootNode.toString();
}

@Override
public <R> SearchStream<E> summarize(Function<? super E, ? extends R> field) {
if (MetamodelField.class.isAssignableFrom(field.getClass())) {
@SuppressWarnings("unchecked")
MetamodelField<E, R> foi = (MetamodelField<E, R>) field;
summaryFields.add(foi);

} else if (TupleMapper.class.isAssignableFrom(field.getClass())) {
@SuppressWarnings("rawtypes")
AbstractTupleMapper tm = (AbstractTupleMapper) field;

IntStream.range(0, tm.degree()).forEach(i -> {
@SuppressWarnings("unchecked")
MetamodelField<E, ?> foi = (MetamodelField<E, ?>) tm.get(i);
summaryFields.add(foi);
});
}
return this;
}

@Override
public <R> SearchStream<E> summarize(Function<? super E, ? extends R> field, SummarizeParams summarizeParams) {
this.summarizeParams = summarizeParams;
return summarize(field);
}

@Override
public <R> SearchStream<E> highlight(Function<? super E, ? extends R> field) {
if (MetamodelField.class.isAssignableFrom(field.getClass())) {
@SuppressWarnings("unchecked")
MetamodelField<E, R> foi = (MetamodelField<E, R>) field;
highlightFields.add(foi);

} else if (TupleMapper.class.isAssignableFrom(field.getClass())) {
@SuppressWarnings("rawtypes")
AbstractTupleMapper tm = (AbstractTupleMapper) field;

IntStream.range(0, tm.degree()).forEach(i -> {
@SuppressWarnings("unchecked")
MetamodelField<E, ?> foi = (MetamodelField<E, ?>) tm.get(i);
highlightFields.add(foi);
});
}
return this;
}

@Override
public <R> SearchStream<E> highlight(Function<? super E, ? extends R> field, Pair<String,String> tags) {
highlightTags = tags;
return highlight(field);
}

public boolean isDocument() {
return isDocument;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.redis.om.spring.search.stream;

import redis.clients.jedis.search.FTSearchParams;

public class SummarizeParams {
public Integer getFragsNum() {
return fragsNum;
}

public Integer getFragSize() {
return fragSize;
}

public String getSeparator() {
return separator;
}

private Integer fragsNum = 3;
private Integer fragSize = 20;
private String separator = "...";

public SummarizeParams fragments(int num) {
this.fragsNum = num;
return this;
}

public SummarizeParams size(int size) {
this.fragSize = size;
return this;
}

public SummarizeParams separator(String separator) {
this.separator = separator;
return this;
}

public static SummarizeParams instance() {
return new SummarizeParams();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.redis.om.spring.metamodel.indexed.NumericField;
import com.redis.om.spring.ops.search.SearchOperations;
import com.redis.om.spring.search.stream.predicates.SearchFieldPredicate;
import com.redis.om.spring.tuple.Pair;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
Expand Down Expand Up @@ -324,4 +325,24 @@ public String backingQuery() {
throw new UnsupportedOperationException("backingQuery is not supported on a WrappedSearchStream");
}

@Override
public <R> SearchStream<E> summarize(Function<? super E, ? extends R> field) {
throw new UnsupportedOperationException("summarize is not supported on a WrappedSearchStream");
}

@Override
public <R> SearchStream<E> summarize(Function<? super E, ? extends R> field, SummarizeParams params) {
throw new UnsupportedOperationException("summarize is not supported on a WrappedSearchStream");
}

@Override
public <R> SearchStream<E> highlight(Function<? super E, ? extends R> field) {
throw new UnsupportedOperationException("highlight is not supported on a WrappedSearchStream");
}

@Override
public <R> SearchStream<E> highlight(Function<? super E, ? extends R> field, Pair<String,String> tags) {
throw new UnsupportedOperationException("highlight is not supported on a WrappedSearchStream");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.redis.om.spring.annotations.hash.fixtures;

import com.redis.om.spring.annotations.Searchable;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;

@Data
@RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(force = true)
@RedisHash
public class Text {
@Id
private String id;

@NonNull
@Searchable
private String body;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.redis.om.spring.annotations.hash.fixtures;

import com.redis.om.spring.annotations.hash.fixtures.Text;
import com.redis.om.spring.repository.RedisDocumentRepository;

public interface TextRepository extends RedisDocumentRepository<Text, String> {
}
Loading