Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hugegraph如何构造query #2415

Open
SkrDrag opened this issue Jan 14, 2024 · 3 comments
Open

Hugegraph如何构造query #2415

SkrDrag opened this issue Jan 14, 2024 · 3 comments
Labels
doc Document expected question Further information is requested

Comments

@SkrDrag
Copy link

SkrDrag commented Jan 14, 2024

Feature Description (功能描述)

以后端数据库为Mysql为例。Hugegraph是如何构造query对象去查询后端数据库的?

@SkrDrag SkrDrag added the feature New feature label Jan 14, 2024
Copy link

dosubot bot commented Jan 14, 2024

🤖

你好 @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包中定义,它有几个子类用于不同类型的查询,如ConditionQueryIdQueryAggregate。这些子类向基类Query添加额外的属性和方法,以支持更复杂的查询。

例如,ConditionQuery类添加了一个conditions属性来存储查询的条件,以及像query()condition()这样的方法来添加查询条件。IdQuery类添加了一个ids属性来存储要查询的ID,以及一个query()方法来添加ID到查询。

关于GraphTransaction类中的optimizeQueries方法如何工作以及它对Query对象执行哪种优化,optimizeQueries方法在GraphTransaction类中用于优化给定的Query对象并返回一系列优化后的查询。优化过程包括展平查询条件并优化每个条件查询。

具体的步骤如下:

  1. 创建一个将保存优化查询的QueryList对象。
  2. 如果查询不是ConditionQuery,将查询添加到QueryList并返回。
  3. 如果查询是ConditionQuery,使用ConditionQueryFlatten.flatten方法展平查询条件。这个方法将复杂的查询条件分解为更简单的条件。
  4. 对于每个展平的ConditionQuery,调用optimizeQuery方法来优化查询。这个方法根据查询的类型和其条件执行几个优化。例如,如果查询是顶点查询并且匹配顶点标签的主键,它通过将顶点标签和主键值转换为顶点id来优化查询。同样,如果查询是边查询并且匹配边标签的排序键,它通过序列化排序值并重置用户属性条件来优化查询。
  5. 如果优化后的查询不为空且不为空,将查询添加到QueryList
  6. 如果优化后的查询为空,调用indexQuery方法执行索引查询并将结果添加到QueryList
  7. 最后,返回包含优化查询的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.

@dosubot dosubot bot added the question Further information is requested label Jan 14, 2024
@SkrDrag
Copy link
Author

SkrDrag commented Jan 14, 2024

🤖

你好 @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包中定义,它有几个子类用于不同类型的查询,如ConditionQueryIdQueryAggregate。这些子类向基类Query添加额外的属性和方法,以支持更复杂的查询。

例如,ConditionQuery类添加了一个conditions属性来存储查询的条件,以及像query()condition()这样的方法来添加查询条件。IdQuery类添加了一个ids属性来存储要查询的ID,以及一个query()方法来添加ID到查询。

关于GraphTransaction类中的optimizeQueries方法如何工作以及它对Query对象执行哪种优化,optimizeQueries方法在GraphTransaction类中用于优化给定的Query对象并返回一系列优化后的查询。优化过程包括展平查询条件并优化每个条件查询。

具体的步骤如下:

  1. 创建一个将保存优化查询的QueryList对象。
  2. 如果查询不是ConditionQuery,将查询添加到QueryList并返回。
  3. 如果查询是ConditionQuery,使用ConditionQueryFlatten.flatten方法展平查询条件。这个方法将复杂的查询条件分解为更简单的条件。
  4. 对于每个展平的ConditionQuery,调用optimizeQuery方法来优化查询。这个方法根据查询的类型和其条件执行几个优化。例如,如果查询是顶点查询并且匹配顶点标签的主键,它通过将顶点标签和主键值转换为顶点id来优化查询。同样,如果查询是边查询并且匹配边标签的排序键,它通过序列化排序值并重置用户属性条件来优化查询。
  5. 如果优化后的查询不为空且不为空,将查询添加到QueryList
  6. 如果优化后的查询为空,调用indexQuery方法执行索引查询并将结果添加到QueryList
  7. 最后,返回包含优化查询的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处理的基本是静态图

Copy link

dosubot bot commented Jan 14, 2024

🤖

🤖

是的,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对不同的操作使用不同类型的事务:

  1. GraphTransaction:这用于对图数据本身的操作。例如,添加或删除顶点和边,查询顶点和边等。这些操作必须手动提交,如graphTransaction()方法中的注释所示。

  2. SysTransaction:这用于系统操作。这些操作也需要手动提交。

  3. SchemaTransaction:这用于对图的模式的操作。每个模式操作将自动提交,如schemaTransaction()方法中的注释所示。

当执行数据更新操作时,使用适当的方法(openGraphTransaction()openSystemTransaction()openSchemaTransaction())打开新的事务。然后在此事务中执行操作。如果操作成功,事务被提交,更改被永久保存。如果操作过程中出现错误,事务被回滚,更改被丢弃。

这种事务模型使HugeGraph能够有效且可靠地处理动态数据更新,确保即使在出现错误或故障的情况下,图数据仍然保持一致和准确。

来源:

这个回答旨在节省你的时间并提供有用的信息。它并不是一个精确的解决方案,而是你自己研究的起点。

帮助我变得更有用!如果这个回答对你有帮助,请给我一个👍,如果这个回答与你的问题无关,请给我一个👎。

如果你想继续这个话题,可以在你的回复开头@dosu-bot

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.

@imbajin imbajin added doc Document expected and removed feature New feature labels Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Document expected question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants