use of org.janusgraph.core.schema.Mapping in project janusgraph by JanusGraph.
the class ElasticSearchIndex method supports.
@Override
public boolean supports(KeyInformation information) {
final Class<?> dataType = information.getDataType();
final Mapping mapping = Mapping.getMapping(information);
if (Number.class.isAssignableFrom(dataType) || dataType == Date.class || dataType == Instant.class || dataType == Boolean.class || dataType == UUID.class) {
return mapping == Mapping.DEFAULT;
} else if (AttributeUtil.isString(dataType)) {
return mapping == Mapping.DEFAULT || mapping == Mapping.STRING || mapping == Mapping.TEXT || mapping == Mapping.TEXTSTRING;
} else if (AttributeUtil.isGeo(dataType)) {
return mapping == Mapping.DEFAULT || mapping == Mapping.PREFIX_TREE;
}
return false;
}
use of org.janusgraph.core.schema.Mapping in project janusgraph by JanusGraph.
the class ElasticSearchIndex method getFilter.
public Map<String, Object> getFilter(Condition<?> condition, KeyInformation.StoreRetriever information) {
if (condition instanceof PredicateCondition) {
final PredicateCondition<String, ?> atom = (PredicateCondition) condition;
Object value = atom.getValue();
final String key = atom.getKey();
final JanusGraphPredicate predicate = atom.getPredicate();
if (value instanceof Number) {
Preconditions.checkArgument(predicate instanceof Cmp, "Relation not supported on numeric types: " + predicate);
final Cmp numRel = (Cmp) predicate;
switch(numRel) {
case EQUAL:
return compat.term(key, value);
case NOT_EQUAL:
return compat.boolMustNot(compat.term(key, value));
case LESS_THAN:
return compat.lt(key, value);
case LESS_THAN_EQUAL:
return compat.lte(key, value);
case GREATER_THAN:
return compat.gt(key, value);
case GREATER_THAN_EQUAL:
return compat.gte(key, value);
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof String) {
final Mapping mapping = getStringMapping(information.get(key));
final String fieldName;
if (mapping == Mapping.TEXT && !(Text.HAS_CONTAINS.contains(predicate) || predicate instanceof Cmp))
throw new IllegalArgumentException("Text mapped string values only support CONTAINS and Compare queries and not: " + predicate);
if (mapping == Mapping.STRING && Text.HAS_CONTAINS.contains(predicate))
throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + predicate);
if (mapping == Mapping.TEXTSTRING && !(Text.HAS_CONTAINS.contains(predicate) || predicate instanceof Cmp)) {
fieldName = getDualMappingName(key);
} else {
fieldName = key;
}
if (predicate == Text.CONTAINS || predicate == Cmp.EQUAL) {
return compat.match(key, value);
} else if (predicate == Text.CONTAINS_PREFIX) {
if (!ParameterType.TEXT_ANALYZER.hasParameter(information.get(key).getParameters()))
value = ((String) value).toLowerCase();
return compat.prefix(fieldName, value);
} else if (predicate == Text.CONTAINS_REGEX) {
if (!ParameterType.TEXT_ANALYZER.hasParameter(information.get(key).getParameters()))
value = ((String) value).toLowerCase();
return compat.regexp(fieldName, value);
} else if (predicate == Text.PREFIX) {
return compat.prefix(fieldName, value);
} else if (predicate == Text.REGEX) {
return compat.regexp(fieldName, value);
} else if (predicate == Cmp.NOT_EQUAL) {
return compat.boolMustNot(compat.match(fieldName, value));
} else if (predicate == Text.FUZZY || predicate == Text.CONTAINS_FUZZY) {
return compat.fuzzyMatch(fieldName, value);
} else if (predicate == Cmp.LESS_THAN) {
return compat.lt(fieldName, value);
} else if (predicate == Cmp.LESS_THAN_EQUAL) {
return compat.lte(fieldName, value);
} else if (predicate == Cmp.GREATER_THAN) {
return compat.gt(fieldName, value);
} else if (predicate == Cmp.GREATER_THAN_EQUAL) {
return compat.gte(fieldName, value);
} else
throw new IllegalArgumentException("Predicate is not supported for string value: " + predicate);
} else if (value instanceof Geoshape && Mapping.getMapping(information.get(key)) == Mapping.DEFAULT) {
// geopoint
final Geoshape shape = (Geoshape) value;
Preconditions.checkArgument(predicate instanceof Geo && predicate != Geo.CONTAINS, "Relation not supported on geopoint types: " + predicate);
final Map<String, Object> query;
switch(shape.getType()) {
case CIRCLE:
final Geoshape.Point center = shape.getPoint();
query = compat.geoDistance(key, center.getLatitude(), center.getLongitude(), shape.getRadius());
break;
case BOX:
final Geoshape.Point southwest = shape.getPoint(0);
final Geoshape.Point northeast = shape.getPoint(1);
query = compat.geoBoundingBox(key, southwest.getLatitude(), southwest.getLongitude(), northeast.getLatitude(), northeast.getLongitude());
break;
case POLYGON:
final List<List<Double>> points = IntStream.range(0, shape.size()).mapToObj(i -> ImmutableList.of(shape.getPoint(i).getLongitude(), shape.getPoint(i).getLatitude())).collect(Collectors.toList());
query = compat.geoPolygon(key, points);
break;
default:
throw new IllegalArgumentException("Unsupported or invalid search shape type for geopoint: " + shape.getType());
}
return predicate == Geo.DISJOINT ? compat.boolMustNot(query) : query;
} else if (value instanceof Geoshape) {
Preconditions.checkArgument(predicate instanceof Geo, "Relation not supported on geoshape types: " + predicate);
final Geoshape shape = (Geoshape) value;
final Map<String, Object> geo;
switch(shape.getType()) {
case CIRCLE:
final Geoshape.Point center = shape.getPoint();
geo = ImmutableMap.of(ES_TYPE_KEY, "circle", ES_GEO_COORDS_KEY, ImmutableList.of(center.getLongitude(), center.getLatitude()), "radius", shape.getRadius() + "km");
break;
case BOX:
final Geoshape.Point southwest = shape.getPoint(0);
final Geoshape.Point northeast = shape.getPoint(1);
geo = ImmutableMap.of(ES_TYPE_KEY, "envelope", ES_GEO_COORDS_KEY, ImmutableList.of(ImmutableList.of(southwest.getLongitude(), northeast.getLatitude()), ImmutableList.of(northeast.getLongitude(), southwest.getLatitude())));
break;
case LINE:
final List lineCoords = IntStream.range(0, shape.size()).mapToObj(i -> ImmutableList.of(shape.getPoint(i).getLongitude(), shape.getPoint(i).getLatitude())).collect(Collectors.toList());
geo = ImmutableMap.of(ES_TYPE_KEY, "linestring", ES_GEO_COORDS_KEY, lineCoords);
break;
case POLYGON:
final List polyCoords = IntStream.range(0, shape.size()).mapToObj(i -> ImmutableList.of(shape.getPoint(i).getLongitude(), shape.getPoint(i).getLatitude())).collect(Collectors.toList());
geo = ImmutableMap.of(ES_TYPE_KEY, "polygon", ES_GEO_COORDS_KEY, ImmutableList.of(polyCoords));
break;
case POINT:
geo = ImmutableMap.of(ES_TYPE_KEY, "point", ES_GEO_COORDS_KEY, ImmutableList.of(shape.getPoint().getLongitude(), shape.getPoint().getLatitude()));
break;
default:
throw new IllegalArgumentException("Unsupported or invalid search shape type: " + shape.getType());
}
return compat.geoShape(key, geo, (Geo) predicate);
} else if (value instanceof Date || value instanceof Instant) {
Preconditions.checkArgument(predicate instanceof Cmp, "Relation not supported on date types: " + predicate);
final Cmp numRel = (Cmp) predicate;
if (value instanceof Instant) {
value = Date.from((Instant) value);
}
switch(numRel) {
case EQUAL:
return compat.term(key, value);
case NOT_EQUAL:
return compat.boolMustNot(compat.term(key, value));
case LESS_THAN:
return compat.lt(key, value);
case LESS_THAN_EQUAL:
return compat.lte(key, value);
case GREATER_THAN:
return compat.gt(key, value);
case GREATER_THAN_EQUAL:
return compat.gte(key, value);
default:
throw new IllegalArgumentException("Unexpected relation: " + numRel);
}
} else if (value instanceof Boolean) {
final Cmp numRel = (Cmp) predicate;
switch(numRel) {
case EQUAL:
return compat.term(key, value);
case NOT_EQUAL:
return compat.boolMustNot(compat.term(key, value));
default:
throw new IllegalArgumentException("Boolean types only support EQUAL or NOT_EQUAL");
}
} else if (value instanceof UUID) {
if (predicate == Cmp.EQUAL) {
return compat.term(key, value);
} else if (predicate == Cmp.NOT_EQUAL) {
return compat.boolMustNot(compat.term(key, value));
} else {
throw new IllegalArgumentException("Only equal or not equal is supported for UUIDs: " + predicate);
}
} else
throw new IllegalArgumentException("Unsupported type: " + value);
} else if (condition instanceof Not) {
return compat.boolMustNot(getFilter(((Not) condition).getChild(), information));
} else if (condition instanceof And) {
final List queries = StreamSupport.stream(condition.getChildren().spliterator(), false).map(c -> getFilter(c, information)).collect(Collectors.toList());
return compat.boolMust(queries);
} else if (condition instanceof Or) {
final List queries = StreamSupport.stream(condition.getChildren().spliterator(), false).map(c -> getFilter(c, information)).collect(Collectors.toList());
return compat.boolShould(queries);
} else
throw new IllegalArgumentException("Invalid condition: " + condition);
}
use of org.janusgraph.core.schema.Mapping in project janusgraph by JanusGraph.
the class ElasticSearchIndex method pushMapping.
/**
* Push mapping to ElasticSearch
* @param store the type in the index
* @param key the name of the property in the index
* @param information information of the key
*/
private void pushMapping(String store, String key, KeyInformation information) throws AssertionError, PermanentBackendException, BackendException {
final Class<?> dataType = information.getDataType();
Mapping map = Mapping.getMapping(information);
final Map<String, Object> properties = new HashMap<>();
if (AttributeUtil.isString(dataType)) {
if (map == Mapping.DEFAULT)
map = Mapping.TEXT;
log.debug("Registering string type for {} with mapping {}", key, map);
final String stringAnalyzer = ParameterType.STRING_ANALYZER.findParameter(information.getParameters(), null);
final String textAnalyzer = ParameterType.TEXT_ANALYZER.findParameter(information.getParameters(), null);
// use keyword type for string mappings unless custom string analyzer is provided
final Map<String, Object> stringMapping = stringAnalyzer == null ? compat.createKeywordMapping() : compat.createTextMapping(stringAnalyzer);
switch(map) {
case STRING:
properties.put(key, stringMapping);
break;
case TEXT:
properties.put(key, compat.createTextMapping(textAnalyzer));
break;
case TEXTSTRING:
properties.put(key, compat.createTextMapping(textAnalyzer));
properties.put(getDualMappingName(key), stringMapping);
break;
default:
throw new AssertionError("Unexpected mapping: " + map);
}
} else if (dataType == Float.class) {
log.debug("Registering float type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "float"));
} else if (dataType == Double.class) {
log.debug("Registering double type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "double"));
} else if (dataType == Byte.class) {
log.debug("Registering byte type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "byte"));
} else if (dataType == Short.class) {
log.debug("Registering short type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "short"));
} else if (dataType == Integer.class) {
log.debug("Registering integer type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "integer"));
} else if (dataType == Long.class) {
log.debug("Registering long type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "long"));
} else if (dataType == Boolean.class) {
log.debug("Registering boolean type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "boolean"));
} else if (dataType == Geoshape.class) {
switch(map) {
case PREFIX_TREE:
final int maxLevels = ParameterType.INDEX_GEO_MAX_LEVELS.findParameter(information.getParameters(), DEFAULT_GEO_MAX_LEVELS);
final double distErrorPct = ParameterType.INDEX_GEO_DIST_ERROR_PCT.findParameter(information.getParameters(), DEFAULT_GEO_DIST_ERROR_PCT);
log.debug("Registering geo_shape type for {} with tree_levels={} and distance_error_pct={}", key, maxLevels, distErrorPct);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "geo_shape", "tree", "quadtree", "tree_levels", maxLevels, "distance_error_pct", distErrorPct));
break;
default:
log.debug("Registering geo_point type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "geo_point"));
}
} else if (dataType == Date.class || dataType == Instant.class) {
log.debug("Registering date type for {}", key);
properties.put(key, ImmutableMap.of(ES_TYPE_KEY, "date"));
} else if (dataType == UUID.class) {
log.debug("Registering uuid type for {}", key);
properties.put(key, compat.createKeywordMapping());
}
if (useAllField && client.getMajorVersion().getValue() >= 6) {
// add custom all field mapping if it doesn't exist
properties.put(ElasticSearchConstants.CUSTOM_ALL_FIELD, compat.createTextMapping(null));
// add copy_to for custom all field mapping
if (properties.containsKey(key) && dataType != Geoshape.class) {
final Map<String, Object> mapping = new HashMap<>(((Map<String, Object>) properties.get(key)));
mapping.put("copy_to", ElasticSearchConstants.CUSTOM_ALL_FIELD);
properties.put(key, mapping);
}
}
final Map<String, Object> mapping = ImmutableMap.of("properties", properties);
try {
client.createMapping(getIndexStoreName(store), store, mapping);
} catch (final Exception e) {
throw convert(e);
}
}
use of org.janusgraph.core.schema.Mapping in project janusgraph by JanusGraph.
the class ElasticSearchIndex method register.
@Override
public void register(String store, String key, KeyInformation information, BaseTransaction tx) throws BackendException {
final Class<?> dataType = information.getDataType();
final Mapping map = Mapping.getMapping(information);
Preconditions.checkArgument(map == Mapping.DEFAULT || AttributeUtil.isString(dataType) || (map == Mapping.PREFIX_TREE && AttributeUtil.isGeo(dataType)), "Specified illegal mapping [%s] for data type [%s]", map, dataType);
final String indexStoreName = getIndexStoreName(store);
if (useExternalMappings) {
try {
// We check if the externalMapping have the property 'key'
final IndexMapping mappings = client.getMapping(indexStoreName, store);
if (mappings == null || (!mappings.isDynamic() && !mappings.getProperties().containsKey(key))) {
// Error if it is not dynamic and have not the property 'key'
throw new PermanentBackendException("The external mapping for index '" + indexStoreName + "' and type '" + store + "' do not have property '" + key + "'");
} else if (mappings.isDynamic()) {
// If it is dynamic, we push the unknown property 'key'
this.pushMapping(store, key, information);
}
} catch (final IOException e) {
throw new PermanentBackendException(e);
}
} else {
try {
checkForOrCreateIndex(indexStoreName);
} catch (final IOException e) {
throw new PermanentBackendException(e);
}
this.pushMapping(store, key, information);
}
}
use of org.janusgraph.core.schema.Mapping in project janusgraph by JanusGraph.
the class ElasticSearchIndex method supports.
@Override
public boolean supports(KeyInformation information, JanusGraphPredicate janusgraphPredicate) {
final Class<?> dataType = information.getDataType();
final Mapping mapping = Mapping.getMapping(information);
if (mapping != Mapping.DEFAULT && !AttributeUtil.isString(dataType) && !(mapping == Mapping.PREFIX_TREE && AttributeUtil.isGeo(dataType)))
return false;
if (Number.class.isAssignableFrom(dataType)) {
return janusgraphPredicate instanceof Cmp;
} else if (dataType == Geoshape.class) {
switch(mapping) {
case DEFAULT:
return janusgraphPredicate instanceof Geo && janusgraphPredicate != Geo.CONTAINS;
case PREFIX_TREE:
return janusgraphPredicate instanceof Geo;
}
} else if (AttributeUtil.isString(dataType)) {
switch(mapping) {
case DEFAULT:
case TEXT:
return janusgraphPredicate == Text.CONTAINS || janusgraphPredicate == Text.CONTAINS_PREFIX || janusgraphPredicate == Text.CONTAINS_REGEX || janusgraphPredicate == Text.CONTAINS_FUZZY;
case STRING:
return janusgraphPredicate instanceof Cmp || janusgraphPredicate == Text.REGEX || janusgraphPredicate == Text.PREFIX || janusgraphPredicate == Text.FUZZY;
case TEXTSTRING:
return janusgraphPredicate instanceof Text || janusgraphPredicate instanceof Cmp;
}
} else if (dataType == Date.class || dataType == Instant.class) {
return janusgraphPredicate instanceof Cmp;
} else if (dataType == Boolean.class) {
return janusgraphPredicate == Cmp.EQUAL || janusgraphPredicate == Cmp.NOT_EQUAL;
} else if (dataType == UUID.class) {
return janusgraphPredicate == Cmp.EQUAL || janusgraphPredicate == Cmp.NOT_EQUAL;
}
return false;
}
Aggregations