29
29
import java .util .function .BiFunction ;
30
30
import java .util .function .Consumer ;
31
31
import java .util .function .Function ;
32
+ import java .util .stream .Collectors ;
32
33
33
34
import org .apache .commons .collections .CollectionUtils ;
34
35
import org .apache .hugegraph .HugeException ;
@@ -1413,8 +1414,7 @@ private <R> QueryList<R> optimizeQueries(Query query,
1413
1414
1414
1415
private Query optimizeQuery (ConditionQuery query ) {
1415
1416
if (query .idsSize () > 0 ) {
1416
- throw new HugeException (
1417
- "Not supported querying by id and conditions: %s" , query );
1417
+ throw new HugeException ("Not supported querying by id and conditions: %s" , query );
1418
1418
}
1419
1419
1420
1420
Id label = query .condition (HugeKeys .LABEL );
@@ -1434,11 +1434,10 @@ private Query optimizeQuery(ConditionQuery query) {
1434
1434
String primaryValues = query .userpropValuesString (keys );
1435
1435
LOG .debug ("Query vertices by primaryKeys: {}" , query );
1436
1436
// Convert {vertex-label + primary-key} to vertex-id
1437
- Id id = SplicingIdGenerator .splicing (label .asString (),
1438
- primaryValues );
1437
+ Id id = SplicingIdGenerator .splicing (label .asString (), primaryValues );
1439
1438
/*
1440
- * Just query by primary-key(id), ignore other userprop (if
1441
- * exists) that it will be filtered by queryVertices(Query)
1439
+ * Just query by primary-key(id), ignore other user-props (if exists)
1440
+ * that it will be filtered by queryVertices(Query)
1442
1441
*/
1443
1442
return new IdQuery (query , id );
1444
1443
}
@@ -1448,25 +1447,60 @@ private Query optimizeQuery(ConditionQuery query) {
1448
1447
// Optimize edge query
1449
1448
if (query .resultType ().isEdge () && label != null &&
1450
1449
query .condition (HugeKeys .OWNER_VERTEX ) != null &&
1451
- query .condition (HugeKeys .DIRECTION ) != null &&
1452
- matchEdgeSortKeys (query , false , this .graph ())) {
1453
- // Query edge by sourceVertex + direction + label + sort-values
1454
- query .optimized (OptimizedType .SORT_KEYS );
1455
- query = query .copy ();
1456
- // Serialize sort-values
1457
- List <Id > keys = this .graph ().edgeLabel (label ).sortKeys ();
1458
- List <Condition > conditions =
1459
- GraphIndexTransaction .constructShardConditions (
1460
- query , keys , HugeKeys .SORT_VALUES );
1461
- query .query (conditions );
1462
- /*
1463
- * Reset all userprop since transferred to sort-keys, ignore other
1464
- * userprop(if exists) that it will be filtered by queryEdges(Query)
1465
- */
1466
- query .resetUserpropConditions ();
1450
+ query .condition (HugeKeys .DIRECTION ) != null ) {
1451
+
1452
+ Directions dir = query .condition (HugeKeys .DIRECTION );
1453
+ EdgeLabel edgeLabel = this .graph ().edgeLabel (label );
1454
+
1455
+ if (query .containsRelation (HugeKeys .OWNER_VERTEX , Condition .RelationType .IN )) {
1456
+ // For IN query, filter schema non-adjacent vertices.
1457
+ ArrayList <Id > vertexIdList = query .condition (HugeKeys .OWNER_VERTEX );
1458
+ List <Id > filterVertexList = vertexIdList .stream ().filter (vertexId -> {
1459
+ Vertex vertex = this .graph ().vertex (vertexId );
1460
+ VertexLabel vertexLabel = graph ().vertexLabel (vertex .label ());
1461
+ return edgeLabel .linkWithVertexLabel (vertexLabel .id (), dir );
1462
+ }).collect (Collectors .toList ());
1463
+
1464
+ if (CollectionUtils .isEmpty (filterVertexList )) {
1465
+ return new Query (query .resultType ());
1466
+ }
1467
+
1468
+ if (vertexIdList .size () != filterVertexList .size ()) {
1469
+ // Modify on the copied relation to avoid affecting other query
1470
+ Condition .Relation relation =
1471
+ query .copyRelationAndUpdateQuery (HugeKeys .OWNER_VERTEX );
1472
+ relation .value (filterVertexList );
1473
+ }
1474
+ } else if (query .containsRelation (HugeKeys .OWNER_VERTEX , Condition .RelationType .EQ )) {
1475
+ Id vertexId = query .condition (HugeKeys .OWNER_VERTEX );
1476
+ Vertex vertex = QueryResults .one (this .queryVertices (vertexId ));
1477
+ if (vertex != null ) {
1478
+ VertexLabel vertexLabel = graph ().vertexLabel (vertex .label ());
1479
+ // For EQ query, just skip query storage if adjacent schema doesn't exist
1480
+ if (!edgeLabel .linkWithVertexLabel (vertexLabel .id (), dir )) {
1481
+ return new Query (query .resultType ());
1482
+ }
1483
+ }
1484
+ }
1467
1485
1468
- LOG .debug ("Query edges by sortKeys: {}" , query );
1469
- return query ;
1486
+ if (matchEdgeSortKeys (query , false , this .graph ())) {
1487
+ // Query edge by sourceVertex + direction + label + sort-values
1488
+ query .optimized (OptimizedType .SORT_KEYS );
1489
+ query = query .copy ();
1490
+ // Serialize sort-values
1491
+ List <Id > keys = this .graph ().edgeLabel (label ).sortKeys ();
1492
+ List <Condition > conditions = GraphIndexTransaction
1493
+ .constructShardConditions (query , keys , HugeKeys .SORT_VALUES );
1494
+ query .query (conditions );
1495
+ /*
1496
+ * Reset all userprop since transferred to sort-keys, ignore other
1497
+ * userprop(if exists) that it will be filtered by queryEdges(Query)
1498
+ */
1499
+ query .resetUserpropConditions ();
1500
+
1501
+ LOG .debug ("Query edges by sortKeys: {}" , query );
1502
+ return query ;
1503
+ }
1470
1504
}
1471
1505
1472
1506
/*
0 commit comments