incubator-hugegraph
incubator-hugegraph copied to clipboard
Hugegraph如何构造query
Feature Description (功能描述)
以后端数据库为Mysql为例。Hugegraph是如何构造query对象去查询后端数据库的?
🤖
你好 @SkrDrag, 我是Dosu,一个可以帮助你解决问题、回答疑问并成为贡献者的机器人。虽然我是机器人,但我在等待人类维护者的同时,会尽力帮助你。很高兴为你服务!
HugeGraph在GraphTransaction
类的query
方法中构造一个查询对象去查询后端数据库。这个方法接受一个Query
对象作为参数,并返回一个QueryResults<BackendEntry>
对象。以下是相关的代码片段:
@Override
public QueryResults<BackendEntry> query(Query query) {
if (!(query instanceof ConditionQuery)) {
// It's a sysprop-query, don't need to optimize
LOG.debug("Query{final:{}}", query);
return super.query(query);
}
QueryList<BackendEntry> queries = this.optimizeQueries(query, super::query);
LOG.debug("{}", queries);
return queries.empty() ? QueryResults.empty() :
queries.fetch(this.pageSize);
}
在这个方法中,如果查询不是ConditionQuery
的实例,它直接调用父类的query
方法。如果它是ConditionQuery
的实例,它调用optimizeQueries
方法来优化查询,然后获取结果。
实际查询后端数据库是在queryVerticesFromBackend
方法中完成的:
protected Iterator<HugeVertex> queryVerticesFromBackend(Query query) {
assert query.resultType().isVertex();
QueryResults<BackendEntry> results = this.query(query);
Iterator<BackendEntry> entries = results.iterator();
Iterator<HugeVertex> vertices = new MapperIterator<>(entries, this::parseEntry);
vertices = this.filterExpiredResultFromBackend(query, vertices);
if (!this.store().features().supportsQuerySortByInputIds()) {
// There is no id in BackendEntry, so sort after deserialization
vertices = results.keepInputOrderIfNeeded(vertices);
}
return vertices;
}
在这个方法中,它调用query
方法获取QueryResults<BackendEntry>
对象,然后使用parseEntry
方法将每个BackendEntry
转换为HugeVertex
对象。它还过滤掉过期的顶点,并在必要时对顶点进行排序。
请注意,与后端数据库交互的query
方法的实际实现在给定的上下文中并未提供。具体的实现将取决于正在使用的后端存储,本例中为MySQL。
关于Query
对象的结构和在query
方法中的使用,Query
对象在HugeGraph中是可以执行对图的不同类型查询的基类。它用于封装查询的参数,如限制、偏移和条件。
在提供的上下文中,Query
对象在constructEdgesQuery
方法中用于创建一个查询,用于检索顶点在两个方向上的所有边。然后,Query
对象被传递给queryEdgesFromBackend
方法来执行查询并检索边。
Query
对象在org.apache.hugegraph.backend.query
包中定义,它有几个子类用于不同类型的查询,如ConditionQuery
、IdQuery
和Aggregate
。这些子类向基类Query
添加额外的属性和方法,以支持更复杂的查询。
例如,ConditionQuery
类添加了一个conditions
属性来存储查询的条件,以及像query()
和condition()
这样的方法来添加查询条件。IdQuery
类添加了一个ids
属性来存储要查询的ID,以及一个query()
方法来添加ID到查询。
关于GraphTransaction
类中的optimizeQueries
方法如何工作以及它对Query
对象执行哪种优化,optimizeQueries
方法在GraphTransaction
类中用于优化给定的Query
对象并返回一系列优化后的查询。优化过程包括展平查询条件并优化每个条件查询。
具体的步骤如下:
- 创建一个将保存优化查询的
QueryList
对象。 - 如果查询不是
ConditionQuery
,将查询添加到QueryList
并返回。 - 如果查询是
ConditionQuery
,使用ConditionQueryFlatten.flatten
方法展平查询条件。这个方法将复杂的查询条件分解为更简单的条件。 - 对于每个展平的
ConditionQuery
,调用optimizeQuery
方法来优化查询。这个方法根据查询的类型和其条件执行几个优化。例如,如果查询是顶点查询并且匹配顶点标签的主键,它通过将顶点标签和主键值转换为顶点id来优化查询。同样,如果查询是边查询并且匹配边标签的排序键,它通过序列化排序值并重置用户属性条件来优化查询。 - 如果优化后的查询不为空且不为空,将查询添加到
QueryList
。 - 如果优化后的查询为空,调用
indexQuery
方法执行索引查询并将结果添加到QueryList
。 - 最后,返回包含优化查询的
QueryList
。
这是相关的代码:
private <R> QueryList<R> optimizeQueries(Query query,
QueryResults.Fetcher<R> fetcher) {
QueryList<R> queries = new QueryList<>(query, fetcher);
if (!(query instanceof ConditionQuery)) {
// It's a sysprop-query, add itself as subquery, don't need to flatten
queries.add(query);
return queries;
}
boolean supportIn = this.storeFeatures().supportsQueryWithInCondition();
for (ConditionQuery cq : ConditionQueryFlatten.flatten(
(ConditionQuery) query, supportIn)) {
// Optimize by sysprop
Query q = this.optimizeQuery(cq);
/*
* NOTE: There are two possibilities for the returned q:
* 1.sysprop-query, which would not be empty.
* 2.index-query result(ids after optimization), which may be empty.
*/
if (q == null) {
queries.add(this.indexQuery(cq), this.batchSize);
} else if (!q.empty()) {
queries.add(q);
}
}
return queries;
}
以上信息来自于:
Sources
This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
If you want to continue the conversation, start your reply with @dosu-bot.
🤖
你好 @SkrDrag, 我是Dosu,一个可以帮助你解决问题、回答疑问并成为贡献者的机器人。虽然我是机器人,但我在等待人类维护者的同时,会尽力帮助你。很高兴为你服务!
HugeGraph在
GraphTransaction
类的query
方法中构造一个查询对象去查询后端数据库。这个方法接受一个Query
对象作为参数,并返回一个QueryResults<BackendEntry>
对象。以下是相关的代码片段:@Override public QueryResults<BackendEntry> query(Query query) { if (!(query instanceof ConditionQuery)) { // It's a sysprop-query, don't need to optimize LOG.debug("Query{final:{}}", query); return super.query(query); } QueryList<BackendEntry> queries = this.optimizeQueries(query, super::query); LOG.debug("{}", queries); return queries.empty() ? QueryResults.empty() : queries.fetch(this.pageSize); }
在这个方法中,如果查询不是
ConditionQuery
的实例,它直接调用父类的query
方法。如果它是ConditionQuery
的实例,它调用optimizeQueries
方法来优化查询,然后获取结果。实际查询后端数据库是在
queryVerticesFromBackend
方法中完成的:protected Iterator<HugeVertex> queryVerticesFromBackend(Query query) { assert query.resultType().isVertex(); QueryResults<BackendEntry> results = this.query(query); Iterator<BackendEntry> entries = results.iterator(); Iterator<HugeVertex> vertices = new MapperIterator<>(entries, this::parseEntry); vertices = this.filterExpiredResultFromBackend(query, vertices); if (!this.store().features().supportsQuerySortByInputIds()) { // There is no id in BackendEntry, so sort after deserialization vertices = results.keepInputOrderIfNeeded(vertices); } return vertices; }
在这个方法中,它调用
query
方法获取QueryResults<BackendEntry>
对象,然后使用parseEntry
方法将每个BackendEntry
转换为HugeVertex
对象。它还过滤掉过期的顶点,并在必要时对顶点进行排序。请注意,与后端数据库交互的
query
方法的实际实现在给定的上下文中并未提供。具体的实现将取决于正在使用的后端存储,本例中为MySQL。关于
Query
对象的结构和在query
方法中的使用,Query
对象在HugeGraph中是可以执行对图的不同类型查询的基类。它用于封装查询的参数,如限制、偏移和条件。在提供的上下文中,
Query
对象在constructEdgesQuery
方法中用于创建一个查询,用于检索顶点在两个方向上的所有边。然后,Query
对象被传递给queryEdgesFromBackend
方法来执行查询并检索边。
Query
对象在org.apache.hugegraph.backend.query
包中定义,它有几个子类用于不同类型的查询,如ConditionQuery
、IdQuery
和Aggregate
。这些子类向基类Query
添加额外的属性和方法,以支持更复杂的查询。例如,
ConditionQuery
类添加了一个conditions
属性来存储查询的条件,以及像query()
和condition()
这样的方法来添加查询条件。IdQuery
类添加了一个ids
属性来存储要查询的ID,以及一个query()
方法来添加ID到查询。关于
GraphTransaction
类中的optimizeQueries
方法如何工作以及它对Query
对象执行哪种优化,optimizeQueries
方法在GraphTransaction
类中用于优化给定的Query
对象并返回一系列优化后的查询。优化过程包括展平查询条件并优化每个条件查询。具体的步骤如下:
- 创建一个将保存优化查询的
QueryList
对象。- 如果查询不是
ConditionQuery
,将查询添加到QueryList
并返回。- 如果查询是
ConditionQuery
,使用ConditionQueryFlatten.flatten
方法展平查询条件。这个方法将复杂的查询条件分解为更简单的条件。- 对于每个展平的
ConditionQuery
,调用optimizeQuery
方法来优化查询。这个方法根据查询的类型和其条件执行几个优化。例如,如果查询是顶点查询并且匹配顶点标签的主键,它通过将顶点标签和主键值转换为顶点id来优化查询。同样,如果查询是边查询并且匹配边标签的排序键,它通过序列化排序值并重置用户属性条件来优化查询。- 如果优化后的查询不为空且不为空,将查询添加到
QueryList
。- 如果优化后的查询为空,调用
indexQuery
方法执行索引查询并将结果添加到QueryList
。- 最后,返回包含优化查询的
QueryList
。这是相关的代码:
private <R> QueryList<R> optimizeQueries(Query query, QueryResults.Fetcher<R> fetcher) { QueryList<R> queries = new QueryList<>(query, fetcher); if (!(query instanceof ConditionQuery)) { // It's a sysprop-query, add itself as subquery, don't need to flatten queries.add(query); return queries; } boolean supportIn = this.storeFeatures().supportsQueryWithInCondition(); for (ConditionQuery cq : ConditionQueryFlatten.flatten( (ConditionQuery) query, supportIn)) { // Optimize by sysprop Query q = this.optimizeQuery(cq); /* * NOTE: There are two possibilities for the returned q: * 1.sysprop-query, which would not be empty. * 2.index-query result(ids after optimization), which may be empty. */ if (q == null) { queries.add(this.indexQuery(cq), this.batchSize); } else if (!q.empty()) { queries.add(q); } } return queries; }
以上信息来自于:
Sources
This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
If you want to continue the conversation, start your reply with @dosu-bot.
Hugegraph有考虑数据动态更新的场景吗。还是说Hugegraph处理的基本是静态图
🤖
🤖
是的,Hugegraph确实支持动态数据更新的场景。这可以从提供的上下文中的
HugeElementFeatures
类看出,该类有supportsAddProperty()
和supportsRemoveProperty()
方法,这两个方法都返回true
。这些方法表明可以向元素(顶点和边)添加和删除属性,从而允许对图数据进行动态更新。这是相关的代码:
public class HugeElementFeatures implements ElementFeatures { @Override public boolean supportsAddProperty() { return true; } @Override public boolean supportsRemoveProperty() { return true; } // ... other methods ... }
HugeGraph通过事务模型处理动态数据更新。HugeGraph的架构设计为以事务方式处理数据更新,确保数据的一致性和完整性。
在提供的代码中,我们可以看到HugeGraph对不同的操作使用不同类型的事务:
GraphTransaction
:这用于对图数据本身的操作。例如,添加或删除顶点和边,查询顶点和边等。这些操作必须手动提交,如graphTransaction()
方法中的注释所示。
SysTransaction
:这用于系统操作。这些操作也需要手动提交。
SchemaTransaction
:这用于对图的模式的操作。每个模式操作将自动提交,如schemaTransaction()
方法中的注释所示。当执行数据更新操作时,使用适当的方法(
openGraphTransaction()
、openSystemTransaction()
或openSchemaTransaction()
)打开新的事务。然后在此事务中执行操作。如果操作成功,事务被提交,更改被永久保存。如果操作过程中出现错误,事务被回滚,更改被丢弃。这种事务模型使HugeGraph能够有效且可靠地处理动态数据更新,确保即使在出现错误或故障的情况下,图数据仍然保持一致和准确。
来源:
- hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeFeatures.java
- hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java
这个回答旨在节省你的时间并提供有用的信息。它并不是一个精确的解决方案,而是你自己研究的起点。
帮助我变得更有用!如果这个回答对你有帮助,请给我一个👍,如果这个回答与你的问题无关,请给我一个👎。
如果你想继续这个话题,可以在你的回复开头@dosu-bot。
Sources
- hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/structure/HugeFeatures.java
- hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/StandardHugeGraph.java
This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
If you want to continue the conversation, start your reply with @dosu-bot.