public Object condition(Object key) { this.checkFlattened(); List<Object> values = new ArrayList<>(); for (Condition c : this.conditions) { if (c.isRelation()) { Condition.Relation r = (Condition.Relation) c; if (r.key().equals(key) && r.relation() == RelationType.EQ) { values.add(r.value()); } } } if (values.isEmpty()) { return null; } E.checkState(values.size() == 1, "Illegal key '%s' with more than one value", key); return values.get(0); }
@Override public int hashCode() { return this.type().hashCode() ^ this.relation().hashCode() ^ this.key().hashCode() ^ this.value().hashCode(); }
/** * This method is only used for secondary index scenario, * its relation must be EQ * @param fields the user property fields * @return the corresponding user property serial values of fields */ public String userpropValuesString(List<Id> fields) { List<Object> values = new ArrayList<>(fields.size()); for (Id field : fields) { boolean got = false; for (Relation r : this.userpropRelations()) { if (r.key().equals(field) && !r.isSysprop()) { E.checkState(r.relation == RelationType.EQ, "Method userpropValues(List<String>) only " + "used for secondary index, " + "relation must be EQ, but got %s", r.relation()); values.add(r.serialValue()); got = true; } } if (!got) { throw new BackendException( "No such userprop named '%s' in the query '%s'", field, this); } } return SplicingIdGenerator.concatValues(values); }
private static Condition flattenIn(Condition condition) { switch (condition.type()) { case RELATION: Relation relation = (Relation) condition; switch (relation.relation()) { case IN: // Flatten IN if needed return convIn2Or(relation); case NOT_IN: // Flatten NOT_IN if needed return convNotin2And(relation); case TEXT_CONTAINS_ANY: // Flatten TEXT_CONTAINS_ANY if needed return convTextContainsAny2Or(relation); default: return condition; } case AND: Condition.And and = (Condition.And) condition; return new Condition.And(flattenIn(and.left()), flattenIn(and.right())); case OR: Condition.Or or = (Condition.Or) condition; return new Condition.Or(flattenIn(or.left()), flattenIn(or.right())); default: throw new AssertionError(String.format( "Wrong condition type: '%s'", condition.type())); } }
@Override protected Query writeQueryCondition(Query query) { ConditionQuery result = (ConditionQuery) query; // No user-prop when serialize assert result.allSysprop(); for (Condition.Relation r : result.relations()) { // Serialize key if (query.resultType().isSchema()) { r.serialKey(((HugeKeys) r.key()).string()); } else { r.serialKey(formatSyspropName((HugeKeys) r.key())); } if (r.value() instanceof Id) { // Serialize id value r.serialValue(writeId((Id) r.value())); } else { // Serialize other type value r.serialValue(JsonUtil.toJson(r.value())); } if (r.relation() == Condition.RelationType.CONTAINS_KEY) { // Serialize has-key String key = (String) r.serialValue(); r.serialValue(formatPropertyName(key)); } } return result; }
private static Set<IndexLabel> matchRangeOrSearchIndexLabels( ConditionQuery query, Set<IndexLabel> indexLabels) { Set<IndexLabel> matchedIndexLabels = InsertionOrderUtil.newSet(); for (Condition.Relation relation : query.userpropRelations()) { if (!relation.relation().isRangeType() && !relation.relation().isSearchType()) { continue; } Id key = (Id) relation.key(); boolean matched = false; for (IndexLabel indexLabel : indexLabels) { if (indexLabel.indexType() == IndexType.RANGE || indexLabel.indexType() == IndexType.SEARCH) { if (indexLabel.indexField().equals(key)) { matched = true; matchedIndexLabels.add(indexLabel); break; } } } if (!matched) { return ImmutableSet.of(); } } return matchedIndexLabels; }
private static boolean matchCondition(BackendEntry item, Condition c) { // TODO: Compatible with BackendEntry TextBackendEntry entry = (TextBackendEntry) item; // Not supported by memory if (!(c instanceof Condition.Relation)) { throw new BackendException("Unsupported condition: " + c); } Condition.Relation r = (Condition.Relation) c; String key = r.serialKey().toString(); // TODO: deal with others Relation like: <, >=, ... if (r.relation() == Condition.RelationType.CONTAINS_KEY) { return entry.contains(r.serialValue().toString()); } else if (r.relation() == Condition.RelationType.CONTAINS) { return entry.containsValue(r.serialValue().toString()); } else if (r.relation() == Condition.RelationType.EQ) { return entry.contains(key, r.serialValue().toString()); } else if (entry.contains(key)) { return r.test(entry.column(key)); } return false; } }
private static Condition convIn2Or(Relation relation) { assert relation.relation() == Condition.RelationType.IN; Object key = relation.key(); @SuppressWarnings("unchecked") List<Object> values = (List<Object>) relation.value(); Condition cond, conds = null; for (Object value : values) { if (key instanceof HugeKeys) { cond = Condition.eq((HugeKeys) key, value); } else { cond = Condition.eq((Id) key, value); } conds = conds == null ? cond : Condition.or(conds, cond); } return conds; }
private static Condition convNotin2And(Relation relation) { assert relation.relation() == Condition.RelationType.NOT_IN; Object key = relation.key(); @SuppressWarnings("unchecked") List<Object> values = (List<Object>) relation.value(); Condition cond; Condition conds = null; for (Object value : values) { if (key instanceof HugeKeys) { cond = Condition.neq((HugeKeys) key, value); } else { cond = Condition.neq((Id) key, value); } conds = conds == null ? cond : Condition.and(conds, cond); } return conds; }
public ConditionQuery query(Condition condition) { // Query by id (HugeGraph-259) if (condition instanceof Relation) { Relation relation = (Relation) condition; if (relation.key().equals(HugeKeys.ID) && relation.relation() == RelationType.EQ) { E.checkArgument(relation.value() instanceof Id, "Invalid id value '%s'", relation.value()); super.query((Id) relation.value()); return this; } } this.conditions.add(condition); return this; }
@Override protected Query writeQueryCondition(Query query) { if (query.resultType().isGraph()) { ConditionQuery result = (ConditionQuery) query; // No user-prop when serialize assert result.allSysprop(); for (Condition.Relation r : result.relations()) { if (r.relation() == Condition.RelationType.CONTAINS) { r.serialValue(JsonUtil.toJson(r.value())); } } } return query; }
private static Condition convTextContainsAny2Or(Relation relation) { assert relation.relation() == Condition.RelationType.TEXT_CONTAINS_ANY; @SuppressWarnings("unchecked") Collection<String> words = (Collection<String>) relation.value(); Condition cond, conds = null; for (String word : words) { assert relation.key() instanceof Id; cond = Condition.textContains((Id) relation.key(), word); conds = conds == null ? cond : Condition.or(conds, cond); } return conds; }
public boolean containsCondition(Condition.RelationType type) { for (Relation r : this.relations()) { if (r.relation().equals(type)) { return true; } } return false; }
public boolean hasSearchCondition() { // NOTE: we need to judge all the conditions, including the nested for (Condition.Relation r : this.relations()) { if (r.relation().isSearchType()) { return true; } } return false; }
public boolean hasSecondaryCondition() { // NOTE: we need to judge all the conditions, including the nested for (Condition.Relation r : this.relations()) { if (r.relation().isSecondaryType()) { return true; } } return false; }
public boolean hasRangeCondition() { // NOTE: we need to judge all the conditions, including the nested for (Condition.Relation r : this.relations()) { if (r.relation().isRangeType()) { return true; } } return false; }
public boolean containsCondition(HugeKeys key, Condition.RelationType type) { for (Relation r : this.relations()) { if (r.key().equals(key) && r.relation().equals(type)) { return true; } } return false; }