org.vertexium.elasticsearch.ElasticSearchSingleDocumentSearchVertexQuery Maven / Gradle / Ivy
package org.vertexium.elasticsearch;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.vertexium.*;
import org.vertexium.elasticsearch.score.ScoringStrategy;
import org.vertexium.query.VertexQuery;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Stream;
import static org.vertexium.util.StreamUtils.stream;
public class ElasticSearchSingleDocumentSearchVertexQuery extends ElasticSearchSingleDocumentSearchQueryBase implements VertexQuery {
private final Vertex sourceVertex;
private Direction direction = Direction.BOTH;
private String otherVertexId;
public ElasticSearchSingleDocumentSearchVertexQuery(
Client client,
Graph graph,
Vertex sourceVertex,
String queryString,
ScoringStrategy scoringStrategy,
IndexSelectionStrategy indexSelectionStrategy,
int pageSize,
Authorizations authorizations
) {
super(client, graph, queryString, scoringStrategy, indexSelectionStrategy, pageSize, authorizations);
this.sourceVertex = sourceVertex;
}
@Override
protected List getFilters(EnumSet elementTypes) {
List filters = super.getFilters(elementTypes);
List relatedFilters = new ArrayList<>();
if (elementTypes.contains(ElasticsearchDocumentType.VERTEX)
|| elementTypes.contains(ElasticsearchDocumentType.VERTEX_EXTENDED_DATA)) {
relatedFilters.add(getVertexFilter(elementTypes));
}
if (elementTypes.contains(ElasticsearchDocumentType.EDGE)
|| elementTypes.contains(ElasticsearchDocumentType.EDGE_EXTENDED_DATA)) {
relatedFilters.add(getEdgeFilter());
}
filters.add(orFilters(relatedFilters));
return filters;
}
private FilterBuilder getEdgeFilter() {
switch (direction) {
case BOTH:
FilterBuilder inVertexIdFilter = getDirectionInEdgeFilter();
FilterBuilder outVertexIdFilter = getDirectionOutEdgeFilter();
return FilterBuilders.orFilter(inVertexIdFilter, outVertexIdFilter);
case OUT:
return getDirectionOutEdgeFilter();
case IN:
return getDirectionInEdgeFilter();
default:
throw new VertexiumException("unexpected direction: " + direction);
}
}
private FilterBuilder getDirectionInEdgeFilter() {
FilterBuilder outVertexIdFilter = FilterBuilders.termFilter(ElasticsearchSingleDocumentSearchIndex.IN_VERTEX_ID_FIELD_NAME, sourceVertex.getId());
if (otherVertexId != null) {
FilterBuilder inVertexIdFilter = FilterBuilders.termFilter(ElasticsearchSingleDocumentSearchIndex.OUT_VERTEX_ID_FIELD_NAME, otherVertexId);
return FilterBuilders.andFilter(outVertexIdFilter, inVertexIdFilter);
}
return outVertexIdFilter;
}
private FilterBuilder getDirectionOutEdgeFilter() {
FilterBuilder outVertexIdFilter = FilterBuilders.termFilter(ElasticsearchSingleDocumentSearchIndex.OUT_VERTEX_ID_FIELD_NAME, sourceVertex.getId());
if (otherVertexId != null) {
FilterBuilder inVertexIdFilter = FilterBuilders.termFilter(ElasticsearchSingleDocumentSearchIndex.IN_VERTEX_ID_FIELD_NAME, otherVertexId);
return FilterBuilders.andFilter(outVertexIdFilter, inVertexIdFilter);
}
return outVertexIdFilter;
}
private FilterBuilder getVertexFilter(EnumSet elementTypes) {
List filters = new ArrayList<>();
List edgeLabels = getParameters().getEdgeLabels();
String[] edgeLabelsArray = edgeLabels == null || edgeLabels.size() == 0
? null
: edgeLabels.toArray(new String[edgeLabels.size()]);
Stream edgeInfos = stream(sourceVertex.getEdgeInfos(
direction,
edgeLabelsArray,
getParameters().getAuthorizations()
));
if (otherVertexId != null) {
edgeInfos = edgeInfos.filter(ei -> ei.getVertexId().equals(otherVertexId));
}
String[] ids = edgeInfos.map(EdgeInfo::getVertexId).toArray(String[]::new);
if (elementTypes.contains(ElasticsearchDocumentType.VERTEX)) {
filters.add(FilterBuilders.idsFilter().ids(ids));
}
if (elementTypes.contains(ElasticsearchDocumentType.VERTEX_EXTENDED_DATA)) {
for (String vertexId : ids) {
filters.add(FilterBuilders.andFilter(
FilterBuilders.termFilter(ElasticsearchSingleDocumentSearchIndex.ELEMENT_TYPE_FIELD_NAME, ElasticsearchDocumentType.VERTEX_EXTENDED_DATA.getKey()),
FilterBuilders.termFilter(ElasticsearchSingleDocumentSearchIndex.EXTENDED_DATA_ELEMENT_ID_FIELD_NAME, vertexId)
));
}
}
return orFilters(filters);
}
private FilterBuilder orFilters(List filters) {
if (filters.size() == 1) {
return filters.get(0);
} else {
return FilterBuilders.orFilter(filters.toArray(new FilterBuilder[filters.size()]));
}
}
@Override
public VertexQuery hasDirection(Direction direction) {
this.direction = direction;
return this;
}
@Override
public VertexQuery hasOtherVertexId(String otherVertexId) {
this.otherVertexId = otherVertexId;
return this;
}
}