将复杂的graphql查询转换为优化的数据库查询。
graphql-compiler的Python项目详细描述
graphql编译器
端到端示例)。
在不久的将来,我们还计划添加来自sqlalchemy元数据的模式自动生成。
有关更详细的概述和入门指南,请参见 我们的博客文章
目录
功能
数据库和查询语言:我们目前支持一个数据库,OrientDB版本2.2.28+,以及OrientDB支持的两种查询语言:Gremlin的OrientDB方言和我们称为Match的OrientDB自己的自定义类SQL查询语言,在其图形遍历运算符的名称之后。对于orientdb,match应该是大多数用户的首选,因为它的运行速度往往比gremlin快,并且具有其他所需的特性。有关详细信息,请参见执行模型部分。
支持关系型数据库,包括PostgreSQL、MySQL、SQLite, Microsoft SQL Server正在进行中。编译器特性的子集可用于 这些数据库。有关更多详细信息,请参见sql部分。
graphql语言特性:我们对graphql语言支持的所有功能的子集进行了优先级排序并实现了这些功能。我们希望随着时间的推移添加更多功能。
端到端示例
尽管这个示例专门针对一个orientdb数据库,但它是泛型的 如何使用GraphQL编译器的端到端示例。
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
定义
- 顶点域:对应于图中某个顶点的域。在下面的示例中,
动物
与实体相关的是顶点字段。animal
字段是查询的字段 开始,因此是根顶点字段。在任何范围内,前缀为out的字段 表示由出站边连接的顶点字段,而在
中前缀为的顶点字段表示 顶点FIELDS通过入站边缘连接。
{ Animal { name @output(out_name: "name") out_Entity_Related { ... on Species { description @output(out_name: "description") } } } }
- 属性字段:与图中顶点的属性相对应的字段。在
上面的示例中,
name
和description
字段是属性字段。在任何给定范围内, 属性字段必须出现在顶点字段之前 - 结果集:将图中的顶点分配给查询中的作用域(位置)。 当数据库处理查询时,可能会创建新的结果集(例如,当遍历边时)。 如果结果集不满足筛选器或类型强制,则可能会丢弃它们。毕竟 部分查询由数据库处理,所有剩余的结果集用于形成 查询结果,在所有标记为输出的属性中取其值。
- 作用域:任何一对大括号之间的查询部分。编译器推断出
每个范围。例如,在上面的查询中,以
animal{
开头的范围是 键入animal
,以out_entity相关{
开头的类型是entity
,并且 从开始…关于物种{
的类型是物种
- 类型强制:生成比
它存在的范围。任何不能满足较窄类型的结果集都将被过滤掉
却没有回来。在上面的查询中,
。关于物种
是一种类型强制 它的类型为entity
的封闭范围,并将其强制为 键入种类
。这是可能的,因为实体
是一个接口,而种类
是一种类型 实现实体
接口。
指令
@可选
如果没有此指令,当查询包含顶点字段时,任何与该查询匹配的结果 必须能够生成该顶点场的值。应用于顶点场, 此指令防止无法为该字段生成值的结果集 被丢弃,并允许继续处理查询的其余部分。
示例使用
{ Animal { name @output(out_name: "name") out_Animal_ParentOf @optional { name @output(out_name: "child_name") } } }
对于每种动物
- 如果它是另一种动物的父母,至少有一行包含
在
名称
和子动物名称
列中分别显示父动物和子动物的名称; - 如果它不是另一种动物的父代,则在
名称
列中有其名称的行, 以及子名称
列中的空值。
约束和规则
@可选
只能应用于顶点字段,根顶点字段除外。- 允许在可选范围内展开顶点字段。
但是,这样做目前与
match
中的性能惩罚相关。
有关详细信息,请参见:展开可选顶点字段。
@recurse
、@fold
或@output_source
不能与@optional
在同一个顶点字段中使用
@output\u source
和@fold
不能在作用域内的任何位置使用
标记为@可选
@可选
只能应用于顶点字段,根顶点字段除外。match
中的性能惩罚相关。
有关详细信息,请参见:展开可选顶点字段。
@recurse
、@fold
或@output_source
不能与@optional
在同一个顶点字段中使用
@output\u source
和@fold
不能在作用域内的任何位置使用
标记为@可选
如果给定的结果集无法为标记为"可选"的顶点字段生成值,
在该顶点字段中,任何标有@output
的字段都返回空值。
当过滤(通过@filter
)或类型强制(通过.)时…适用于动物
在标记为
@optional
的顶点字段处或其内,优先使用@optional
:
- 如果给定的结果集无法生成可选顶点字段的值,则将保留该值:
首先应用
@可选的
指令,不进行筛选或类型强制开可能发生。 - 如果给定的结果集能够生成可选顶点场的值,
@可选的
不适用,然后根据筛选或类型检查该值 强迫。这些后续操作可能会导致结果集被丢弃 不匹配。
例如,假设我们有两个名为albert
和betty
的人
顶点,这样就有一个人
从albert
到betty
的边
然后执行以下查询:
{ Person { out_Person_Knows @optional { name @filter(op_name: "=", value: ["$name"]) } name @output(out_name: "person_name") } }
使用运行时参数
{"name":"Charles"}
会输出一个空列表,因为 然而,如果没有这样的 因为没有这样的边可以满足 表示属性字段的值应包含在输出中。
其 此查询返回图形中每个 如果标记为 将 每个返回的行有两列: 下面的graphql是不允许的,它将生成一个graphqlcompilationerror。
此查询无效,原因有两个: 以下是 要向 此查询返回的每一行在 允许根据一组筛选操作中的任何一个来筛选要返回的数据。
从概念上讲,它相当于sql 请参见支持的筛选操作
有关编译器当前支持的各种类型筛选的详细信息。
这些操作目前是在编译器中硬编码的;将来,
我们可以通过编译器插件添加自定义筛选操作。 可以同时对同一字段应用多个 允许使用引用同一顶点内标记的 运行时参数用前缀(例如 考虑以下问题: 它为每个 标记的参数用前缀(例如 考虑以下问题: 它返回包含父母名字的动物的名字作为自己的子串。
数据库将父动物名称的值捕获为 我们考虑并拒绝了允许文字值的想法(例如 应用于顶点场,指定将该顶点场连接到当前
顶点应该被重复访问,直到 假设用户想要获取每个 如果用户还想将曾孙添加到 此查询返回的每一行都包含 使用此指令的递归是可能的,因为封闭作用域和递归的类型
作用域计算:recurse 由于 现在,让我们看看当我们消除外部 在这种情况下,当递归开始于 支持的比较运算符: 这将为每个 这将为每个 允许您在包含精确字符串 这将为名称和/或别名等于 为 返回: 这将为每个 这将为每个 这将为其名称包含所提供值的每个 这将为其别名列表包含所提供值的每个 这将为其别名列表不包含所提供值的每个 这将为其别名列表具有非空交集的每个 这将为每个具有 顶点字段中的 注意:请注意上面正在过滤的顶点字段上的 类型强制是创建类型不同于
强制的封闭范围——它们将封闭范围强制为不同的类型。
类型强制用graphql内联片段表示。 在这里, 在此查询中,与 编译器支持标准的graphql元字段 此查询为每个 元字段是由graphql编译器定义的非标准元字段,它使
可以与标记为 我们使用前缀来表示这是编译器引入的扩展元字段,
不是由graphql规范定义的graphql元字段规范集的一部分。
我们不对元字段使用graphql标准双下划线( 由于 这样做的首选方法是使用 如果您不能以编程方式定义模式,而只是预先创建一个
graphql schema对象,您可以对其进行变异,另一种方法是通过
此查询为每个 在这里,我们修改了上面的查询,为返回的行添加了另外两个过滤约束: 重要的是,在任何其他过滤器和类型强制之后,对 和 在这两个查询中,我们都会要求具有
当我们在物种的 与 在第一种情况下,为了进行 本节假设读者熟悉模式在
Graphql的参考实现 与编译器一起使用的graphql模式必须包含自定义指令和自定义日期。
以及编译器定义的标量类型
如果以编程方式构造模式,可以简单地导入python对象
自定义指令和自定义类型的表示: 因为graphql和orientdb类型的系统有不同的规则,所以没有一个适合所有类型的系统
为给定数据库模式编写graphql模式的解决方案。
但是,请记住以下经验法则: 因为graphql编译器可以针对多个不同的查询语言,每个语言都有自己的
行为和限制,执行模型还必须定义为
编译目标语言。当我们努力缩小
编译目标,有些差异是不可避免的。 编译器遵循以下原则: 为了更详细地解释返回结果的完整性,假设数据库包含
下面的示例图: 设 考虑graphql查询: 在数据库中的数据和查询的结构之间,很明显
这正是 由于 由于底层查询语言的限制, 用户可以对查询的最后一个作用域应用 查询现在不会为每个 从概念上讲,应用 下表概述了graphql编译器的特性,以及它们对各种
关系数据库风格: 通过编译到sqlalchemy core作为中介支持关系数据库
语言,然后依赖于sqlalchemy编译的特定于方言的sql字符串来查询
目标数据库。 对于sql后端,假定graphql类型有一个同名的sql表,并且
相同的属性。例如,模式类型 应与同名的SqlAlchemy表对象相对应,不区分大小写。为此
架构类型可能如下: 如果架构类型名的表不存在,则在编译时将引发异常。见
配置SQL数据库以匹配GraphQL架构
以获得解决此类命名差异的可能选项。 下面是一个端到端的示例,包括相关的graphql模式和sqlalchemy引擎准备。 这旨在显示graphql编译器的sql后端的设置步骤,以及
不代表在生产系统中配置和运行sqlalchemy的最佳实践。 为了简单起见,sql后端要求sqlalchemy表和grap之间完全匹配HQL类型,
在sqlalchemy列和graphql字段之间。如果表名或列名在
数据库不符合这些规则?最终的计划是
SQL后端更可配置。在短期内,解决这一问题的一种可能方法是使用
SQL视图。 例如,假设数据库中有一个名为 然后可以通过如下视图将其曝光: 此时,可以在sqlalchemy表中使用 要进行漂亮的打印图形查询,请使用附带的漂亮打印机: 它以python的 在graphql中包含可选语句本身没有性能问题,
但是如果你继续在一个可选范围内扩展顶点场,
可能会对性能产生重大影响。 接下来,我们将介绍两种不同的可选指令。 orientdb 目前,这不能用一个简单的 相反,我们用两个不同的union( 在第一种情况下,如果不遵循可选边,
我们必须显式地过滤掉边可能被跟踪的所有顶点。
这是为了消除两个"匹配"选项之间的重复。 前面的例子并不是我们如何实现复合选项
(我们还有 如果在给定的图形中有许多复合选项,
上述过程导致大量 因此,我们得到的性能惩罚是指数增长的
具有个复合边个可选边。
在使用许多可选指令编写查询时,记住这一点非常重要。 如果其中一些复合选项包含自己的顶点字段,
由于我们必须把所有的P可选 此编译参数是解决graphql和gremlin限制的一种方法。
键入系统: 假设以下graphql模式: 这里适当的 在编译过程中设置 当从数据库元数据构建graphql模式时,我们首先从
元数据,然后从 有关如何构建和使用 在将来,我们计划添加从sqlalchemy元数据生成的schemagraph redisgraph不支持查询参数,因此我们在
函数 相反,neo4j cypher的正确方法如下:给定一个名为 有关自定义标量类型的描述、序列化和解析的信息
从字符串解析graphql架构时,对象将丢失。当
使用自定义标量类型对象。为了避免这些问题,可以使用代码
下面的代码片段用于修改编译器使用的自定义标量类型的定义。 q:您是真的使用graphql,还是只使用类似graphql的语法? A:我们真的用GraphQL。编译器将接受的任何查询都是完全有效的graphql,
实际上,我们使用graphql核心库的python端口进行解析和类型检查。
但是,由于编译graphql生成的数据库查询受到限制
的它们运行在数据库系统上,我们的执行模型与
标准graphql规范中描述的那个。见
执行模型部分了解更多详细信息。 q:这个项目是否附带了graphql服务器实现? A:不——有很多现有的框架可以用来运行Web服务器。我们只是建立了一个工具
它接受graphql查询字符串(及其参数)并返回一个查询字符串
与数据库一起使用。编译器不针对数据库执行查询字符串,
它也不会反序列化结果。因此,选择
使用服务器框架和数据库客户端库。 Q:您是否计划在未来支持其他数据库/更多GraphQL功能? A:我们很乐意,我们真的需要你的帮助!请考虑参与这个项目
通过打开问题、打开拉取请求或参与讨论。 问:我想我发现了一个虫子,我该怎么办? A:请检查是否已经为该bug创建了问题,如果没有,请打开一个新的问题。
确保尽可能详细地描述错误,包括任何堆栈跟踪或
您可能看到的错误消息、正在使用的数据库以及编译的查询。 问:我想我发现了一个安全漏洞,该怎么办? A:请联系我们
graphql compiler mainter@kensho.com
因此,我们可以对问题进行分类并采取适当的措施。 根据Apache2.0许可证授权。除非适用法律要求或书面同意,
根据许可证分发的软件按"原样"分发,无需保证或
任何形式的条件,无论是明示的还是默示的。请参阅特定语言的许可证
管理许可下的权限和限制。 版权所有2017-至今Kensho Technologies,LLC。当前日期由时间戳确定
存储库中最新提交的。您知道的人
从
albert
到betty
的边满足了@可选的
指令,但是
betty
与对名为charles
的节点的筛选器检查不匹配
人知道从
albert
存在边缘,那么输出将是{name:'Albert'}
@可选的
指令,并且不会进行过滤。@输出
out_name
参数指定
应返回输出值。示例使用
{
Animal {
name @output(out_name: "animal_name")
}
}
动物的名称,在名为
动物名称
的列中。
指令应用于约束和规则
@输出
只能应用于属性字段。out_name
提供的值只能由大写或小写字母组成
(a-z
,a-z
)或下划线(/code>)。
out_name
提供的值不能以\uu
作为前缀(三个下划线)。这个
命名空间保留给编译器内部使用。out_name
值都必须是唯一的。换句话说,输出列必须
有唯一的名字。@output
的属性字段存在于标记为@optional
的范围内,则结果设置为
无法将值赋给可选作用域返回值null
作为输出
属性字段的值。@折叠
@fold
应用于范围"折叠"该范围内的所有输出:而不是显示
在查询结果中的单独行上,折叠的输出被合并成列表,开始
在标有@fold的范围内
示例使用
{
Animal {
name @output(out_name: "animal_name")
out_Animal_ParentOf @fold {
name @output(out_name: "child_names")
}
}
}
animal_name
在图中每个animal的名称,
以及
子动物名
以及动物名
的所有子动物名列表。
如果给定的动物
没有子项,则其子名称
列表为空。约束和规则
@fold
只能应用于顶点字段,根顶点字段除外。@recurse
、@optional
或@output\u source
>的同一顶点字段中
@fold
标记或嵌套在@fold
标记范围内的作用域,
最多可以展开一个顶点场。@fold
范围内必须至少有一个@output
字段。@fold
遍历中的所有@output
字段都必须出现在最里面的作用域中。
遇到@output
指令后,在@fold
中展开顶点字段是无效的。@标记
,@递归
,@可选
,@输出源
和@fold
不能在任何地方使用
在标有@fold的范围内
@filter
@允许折叠
。
只有满足给定类型强制和筛选器的数据才会由@fold
@fold
作用域中的类型强制实际上是一个no op,
它可以优化它。见
可选的类型戋u equivalence戋u提示
编译参数
部分了解更多详细信息。示例
@output
指令(outputtinganimal\u name
)之后展开顶点字段
范围,位于标记为
@fold
的范围内,
扩展两个顶点场而不是最多一个。
0
pip install graphql-compiler
@fold的有效用法:
:
1
pip install graphql-compiler
@标签
@tag
指令允许根据同一查询中其他地方遇到的值进行筛选。
应用于属性字段,它为该属性字段的值指定一个名称,允许
值,然后用作@filter
指令的一部分。@filter
指令提供标记值,请放置标记名(前缀为%
符号)
在@filter
'svalue
数组中。请参见传递参数
有关详细信息。示例使用
2
pip install graphql-compiler
子名称
列中包含动物的名称
它是另一种动物的后代,其名称在词汇上小于
其母公司的名称。约束和规则
@标记
只能应用于属性字段。标记名
提供的值只能由大写或小写字母组成
(a-z
,a-z
)或下划线(/code>)。
@fold的范围内的属性字段
@tag
和@filter
,
只要两者不出现在完全相同的属性字段中。@过滤器
where
关键字的graphql。@filter
指令。在概念上,
这就好像不同的@filter
指令是由sql和
关键字连接起来的。@tag
和@filter
,
只要两者不出现在完全相同的属性字段中。传递参数
@filter
指令接受两种类型的参数:运行时参数和标记的参数。$foo
)表示,并表示参数
其值将在运行时已知。编译器将编译graphql查询,留下
在运行时填充值的点。编译后,用户必须为
所有运行时参数及其值将被插入到最终查询中,然后
对检察官执行死刑表<<P>
3
pip install graphql-compiler
animal
顶点返回一行,该顶点的颜色等于$animal\u color
。每行
在名为"动物名"的列中包含动物名。参数$animal_color
是
一个运行时参数——用户必须传入一个值(例如{"animal\u color":"blue"}
)
将在查询数据库之前插入查询。%foo
)表示,并表示参数
其值派生自查询中其他地方遇到的属性字段。
如果用户使用@tag
指令和适当的名称标记属性字段,
该值可用作所有后续@filter
指令中的标记参数。
4
pip install graphql-compiler
父动物名称
标记,然后
然后将值用作子动物的@filter
中的%parent_name
标记参数123
)
作为@filter
参数,有几个原因:@filter
指令的值字段的graphql类型不能合理地包含
人们可能提供的所有不同类型的论据。即使只计算标量类型,
已经有了
id,int,float,boolean,string,date,datetime…
--太多了,无法包含。约束和规则
op_name
提供的值只能由大写或小写字母组成
(a-z
,a-z
)或下划线(/code>)。
值
列表中提供的值必须以$
开头
(表示运行时参数)或%
(表示标记参数)。
后跟大写或小写字母(a-z
,a-z
)或下划线(/code>)。
@filter
查询中的任何标记参数对应的@tag
指令
必须应用于与带有@filter
的字段位于同一顶点的字段,
或者严格在带有@filter
指令的字段之前。@filter
的参数的graphql类型
必须与编译器根据应用@filter
的字段推断的GraphQL类型匹配。@tag
来自顶点字段中
标记为@optional
,发出的@filter
代码检查@optional
字段是否
分配了一个值。如果没有值是assi登录到@optional
字段,与
从该字段中标记的参数返回true
。
%from_optional
源于@optional
作用域,当没有值时
分配给@可选的
字段:
@filter(op_name:"=",值:[%from_optional"])
等同于not
有过滤器;@filter(op_name:"between",value:["$lower","%from_optional"])
相当于
@filter(操作名:">;=",值:["$lower"])
@tag
和@filter
,
只要两者不出现在完全相同的属性字段中。@递归
depth
次。递归总是开始的
在深度=0时,即当前顶点--请参见以下各节以获得更详细的解释。
示例使用
动物的子孙的名字。
这可以通过运行以下两个查询并连接它们的结果来完成:
5
pip install graphql-compiler
6
pip install graphql-compiler
子代
输出中,则
需要另一个查询,依此类推。而不是连接多个查询的结果,
用户只需使用@recurse
指令即可。下面的查询返回
孙辈:
7
pip install graphql-compiler
祖先
列中
动物的名称
以及其子代或孙代的名称。
标记为"递归"的顶点字段的"输出动物"父字段已包含在
另一个
out_animal_parentof
顶点字段,因此递归从
"child"级别(未用@recurse
标记的输出动物的父级)。
因此,
后代
列包含祖先
的名称
子级(从递归的depth=0
开始)及其子级的名称(从depth=1
开始)。animal
类型的顶点字段
它的顶点域被封装在animal
类型的范围内。
下面将详细介绍允许递归的其他情况。@递归,因此
后代
列不能有祖先
动物的名称
已经在一个out_animal_parentof
中,而不是在根animal
顶点字段中。
同样,它不能删除超过两个步骤的子代
(例如,曾孙),因为@recurse
的depth
参数设置为1
out_animal_parentof
顶点字段时会发生什么
只需将@recurse
应用于根顶点字段作用域中的out\u animal父对象
,必须至少满足以下条件之一:
8
pip install graphql-compiler
depth=0
时,递归范围内的动物
在根顶点字段的
animal
将相同,因此,在
递归,self_或_后代的值将等于
"祖先"字段。
约束和规则
a
的范围内应用时,
到a
是一个graphql联合体;b
是一个graphql接口,a
是实现该接口的类型;a
和b
是同一类型。@recurse
只能应用于查询的根顶点字段以外的顶点字段。@可选
或@折叠
的范围内使用
depth
参数的值必须始终大于或等于1。
使用depth=1
沿
指定边缘。@filter
指令不限制
递归深度。概念上,先递归到指定深度,
然后类型强制和@filter
指令消除一些到达的位置
通过递归。@recurse的顶点字段
@输出源
约束和规则
@可选
或@折叠
的范围内使用
支持的筛选操作
比较运算符
=
!=
>;
<;
>;=
<;=
示例使用
等于(
=
):
9
pip install graphql-compiler
物种返回一行,其名称等于
$物种名称的值
参数。每一行在名为species_uid
的列中包含uuid
的species_uid
的
中大于或等于(
>;=
):fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
0
动物
顶点返回一行,该顶点是在$point_in_time
之后或之上出生的。
每行分别在名为name
和birthday
的列中包含动物的名称和生日。约束和规则
姓名或别名
$wanted_name_或_alias的顶点上进行筛选
名称
或别名
字段。示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
1
$所需名称或别名的每个
,动物
顶点返回一行。
每一行在名为name
的列中包含动物的名称。
$wanted_name_或_alias
提供的值必须是动物的全名和/或别名。
子字符串将不匹配。
约束和规则
名称
和别名
属性的顶点字段上。介于
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
2
$lower
和$upper
日期(含)之间的每个动物
顶点,一行。
每一行在名为name
的列中包含动物的名称。
约束和规则
收藏中
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
3
动物
顶点返回一行,该顶点的颜色包含在颜色列表中。
每一行分别在名为动物名
和颜色
的列中包含动物的名称和颜色。
约束和规则
不在集合中
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
4
动物
顶点返回一行,该顶点的颜色不包含在颜色列表中。
每一行分别在名为动物名
和颜色
的列中包含动物的名称和颜色。
约束和规则
有_子串
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
5
动物
顶点返回一行
对于
$substring
参数。每行包含匹配的动物名
在名为"动物名"的列中约束和规则
包含
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
6
动物
顶点返回一行
对于
$想要的
参数。每行包含匹配的动物名
在名为"动物名"的列中约束和规则
不包含
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
7
动物
顶点返回一行
对于
$想要的
参数。每行包含匹配的动物名
在名为"动物名"的列中约束和规则
相交
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
8
动物
顶点返回一行
以及为
,
无法生成有效的结果集,结果查询将不返回任何结果。$wanted
参数提供的值列表。
每一行在名为"动物名"的列中都包含匹配的动物名。
约束和规则
有边缘度
示例使用
fromgraphql.utils.schema_printerimportprint_schemafromgraphql_compilerimport(get_graphql_schema_from_orientdb_schema_data,graphql_to_match)fromgraphql_compiler.schema_generation.orientdb.utilsimportORIENTDB_SCHEMA_RECORDS_QUERY# Step 1: Get schema metadata from hypothetical Animals database.client=your_function_that_returns_an_orientdb_client()schema_records=client.command(ORIENTDB_SCHEMA_RECORDS_QUERY)schema_data=[record.oRecordDataforrecordinschema_records]# Step 2: Generate GraphQL schema from metadata.schema,type_equivalence_hints=get_graphql_schema_from_orientdb_schema_data(schema_data)print(print_schema(schema))# schema {# query: RootSchemaQuery# }## directive @filter(op_name: String!, value: [String!]!) on FIELD | INLINE_FRAGMENT## directive @tag(tag_name: String!) on FIELD## directive @output(out_name: String!) on FIELD## directive @output_source on FIELD## directive @optional on FIELD## directive @recurse(depth: Int!) on FIELD## directive @fold on FIELD## type Animal {# name: String# net_worth: Int# limbs: Int# }## type RootSchemaQuery{# Animal: [Animal]# }# Step 3: Write GraphQL query that returns the names of all animals with a certain net worth.# Note that we prefix net_worth with '$' and surround it with quotes to indicate it's a parameter.graphql_query='''{ Animal { name @output(out_name: "animal_name") net_worth @filter(op_name: "=", value: ["$net_worth"]) }}'''parameters={'net_worth':'100',}# Step 4: Use autogenerated GraphQL schema to compile query into the target database language.compilation_result=graphql_to_match(schema,graphql_query,parameters,type_equivalence_hints)print(compilation_result.query)# SELECT Animal___1.name AS `animal_name` # FROM ( MATCH { class: Animal, where: ((net_worth = decimal("100"))), as: Animal___1 } # RETURN $matches)
9
$child\u count
子节点的动物
顶点返回一行
(即,当out_animal_parentof
边正好出现$child_count
次)。
每一行都包含匹配的动物名,在名为动物名的列中。
uuid
字段被添加以满足
graphql语法规则,要求任何{}
中至少存在一个字段。
由于此字段未标记任何指令,因此对查询没有影响。@optional
指令。
如果在您的用例中希望将$child\u count
设置为0,则还必须将其标记为
顶点字段@可选
。回想一下,没有@optional
意味着至少有一个
这样的边缘一定存在。如果将参数设置为0时使用has_edge_degree
过滤器,
这就要求边缘不存在。因此,如果在此情况下不存在可选的约束和规则
0
,则强烈建议也应用
@可选
到要过滤的顶点字段(有关详细信息,请参见上面的N.B.)。类型强制
示例使用
{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
0
out-species\u eats
顶点字段是union-foodorspecies\u-species
union类型。继续进行
使用查询时,用户必须选择要使用的union\u foodorspecies\u species
union中的哪些类型。
在本例中,。on food
表示选择了food
类型,以及任何顶点
在该范围内,不属于类型的食物被过滤掉并丢弃。
{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
1
输出实体相关的
属于实体
类型。但是,查询只想
返回结果,其中相关实体是物种
,该物种
。关于物种
确保是这样。元字段
_类型名
\u typename
,它返回运行时类型
字段所在范围的。假设graphql模式与数据库的模式匹配,
运行时类型将始终是作用域的静态类型的子类型(或完全等于)
由graphql类型系统确定。下面,我们提供一个示例查询,其中
运行时类型是静态类型的子类型,但不等于静态类型。\u typename
字段被视为字符串类型的属性字段,并支持
可应用于任何其他属性字段的所有指令。
示例使用
{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
2
实体
顶点返回一行。出现\u typename
的范围是
静态类型实体
。然而,动物
是一种实体
,物种食物
,
以及其他。因此,将返回实体
的所有子类型的顶点,并且实体类型
输出\u typename
字段的列将显示它们的运行时类型:动物
,物种
,
食物
等
x_计数
@fold
的作用域中元素的个数进行交互。通过应用指令
与@output
和@filter
一样,查询可以输出捕获的元素数
在@fold
中,向下筛选结果以仅选择具有所需折叠大小的折叠。\uu
)前缀,
因为所有带那个前缀的名字
显式保留,禁止使用
在指令、字段或任何其他工件中。将
\u x\u count
元字段添加到架构中
\u x\u count
元字段当前不是graphql标准的一部分,因此必须
显式添加到架构中的所有接口和类型。有两种方法可以做到这一点。extended_meta_field_definitions
常量
构建接口和类型字段描述的起点注:{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
3
将元字段插入现有模式中
编译器定义的帮助函数:{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
4
示例使用
{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
5
动物
顶点返回一行。每行包含其名称、编号和名称
它的孩子们。虽然
子名称选择的输出类型是字符串列表,
number_of_children
选项的输出类型是一个整数。{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
6
animal
顶点必须包含$substr
的值作为其名称中的子字符串,并且
动物
顶点必须至少有满足上述过滤器的$min_子节点
子节点。\u x\u count
的任何过滤都将应用。
出现在问题中的@fold
中。这种操作顺序非常重要:选择
动物
有3个以上子节点的顶点,然后根据其名称筛选子节点不相同
先过滤子节点,然后选择有3个以上子节点的动物节点
与先前的过滤器匹配。约束和规则
@fold
的顶点字段中出现@count
字段
\u x\u count
上应用筛选
在那里面@fold
\u x\u count
字段的值必须始终在最里面进行
折叠的范围。在过滤后展开@fold
中的顶点字段是无效的
或输出"元"字段的值。在
\u x_count
上过滤与@filter
具有的has_edge_degree
有何不同?has_edge_degree
过滤器允许根据特定类型的边数进行过滤。
在某些情况下,使用进行过滤具有边缘度
,使用=
进行过滤时,使用\u x\u count
生成等效查询。这里有一对这样的查询:{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
7
{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
8
$num_anims
成员。然而,我们用两种不同的方式表达了这个问题:一次
作为物种
顶点的一个属性("物种的程度是
$num动物
",
一次作为@fold
生成的动物
顶点列表的属性
@fold
中的元素是$num_anims
"。顶点的
内添加额外的过滤时
场,这个区别变得非常重要。比较以下两个查询:
{
Animal {
name @output(out_name: "name")
out_Entity_Related {
... on Species {
description @output(out_name: "description")
}
}
}
}
9
{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
0
has_edge_degree
过滤,动物的位置
live是不相关的:具有边缘度
只确保物种
顶点具有
正确的类型的边的数目,就这样。相反,第二个查询
确保只有
物种
顶点有$num_动物
生活在选定区域中的动物
返回位置——位置很重要,因为@filter
在\u x\u count
字段中适用
到@fold
范围中的元素数。graphql模式
{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
1
{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
2
a
和b
这样
b
继承自a
,您有两个选项:
a
OrientDB类表示为GraphQL接口,
与b
相对应的graphql类型可以实现的。
在本例中,graphql模式保留继承关系
在a
和b
之间,但牺牲了任何继承关系的表示
a
可以与任何orientdb超类一起使用。a
和b
都表示为graphql类型。在这种情况下的权衡是
与前面的情况正好相反:graphql模式
牺牲a
和b
之间的继承关系,但保留
a
与其超类的继承关系。
在这种情况下,建议创建graphql联合类型a b
,
并将该graphql联合类型用于
在OrientDB中,类型为A
a
和b
b
继承自a
,您同样有两个选项:
b
表示为可以实现graphql接口的graphql类型
对应于a
。这使得graphql模式保留继承关系
介于a
和b
之间,但牺牲了其他graphql类型从b
继承的能力。
a
和b
都表示为graphql接口,牺牲模式的
表示a
和b
之间的继承,但允许graphql类型
从a
和b
继承。如果需要,可以创建一个graphql
union typea b
并将其用于orientdb中类型为a
的任何顶点字段embeddedmap
类型或嵌入的非基元类型字段,
因此,在类的graphql表示中可以简单地省略这些字段。
或者,可以省略整个orientdb类和可能指向它的所有边
完全来自graphql模式。执行模型
gremlin
,match
和sql
以表格格式返回数据,其中每个结果都是
表中的一行和标记为输出的字段是列。匹配
编译目标保证生成完整的结果。返回结果的完整性
{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
3
a、b、x、y
为四个顶点的name
属性字段的值。
让名为a
和b
的顶点为s
类型,让x
和y
为t
类型。
让顶点a
通过e
类型的有向边连接到x
和y
上。
类似地,让vertexb
也通过e
类型的有向边连接到x
和y
。
{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
4
a
或b
使用x
或y
中的任何一个都会产生有效的结果。因此,
这里以json格式显示的完整结果列表将是:{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
5
match
编译目标保证产生的结果。
本节的其余部分仅适用于gremlin
编译目标。如果使用
匹配
,本节其余部分中列出的所有查询都将生成相同的完整查询
结果列表。gremlin
编译目标不能保证完整的结果列表,
使用由gremlin
编译目标生成的查询字符串查询数据库
将只生成类似以下内容的部分结果列表:{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
6
gremlin
将默认最多生成一个
查询中每个起始位置的结果。上面的graphql查询开始于
类型s
,因此返回结果列表中的每个s\u name
都是不同的。此外,
无法保证(也无法提前知道)是否x
或y
将作为
每个结果中的t_name
值,因为它们都是有效的结果。@output\u source
指令
要改变此行为:{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
7
s
最多生成一个结果,而是生成
最多只能有一个结果对于每个可以在out\u e
中找到的不同值,其中
已应用:{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
8
@output\u source
指令会使查询看起来是在
相反的顺序:{
Animal {
name @output(out_name: "name")
out_Animal_ParentOf @optional {
name @output(out_name: "child_name")
}
}
}
9
SQL
< /广告><正文>特色/方言
所需边 @过滤器
@输出
@递归
@折叠
@可选
@输出源
PostgreSQL <不< < > >受限制,相交,有懔edge懔degree,并且不支持筛选器 有限,不支持输出元字段
<不< < > ><不< < > ><不< < > ><不< < > > sqlite <不< < > >受限制,相交,有懔edge懔degree,并且不支持筛选器 有限,不支持输出元字段
<不< < > ><不< < > ><不< < > ><不< < > > Microsoft SQL Server <不< < > >受限制,相交,有懔edge懔degree,并且不支持筛选器 有限,不支持输出元字段
<不< < > ><不< < > ><不< < > ><不< < > > mysql <不< < > >受限制,相交,有懔edge懔degree,并且不支持筛选器 有限,不支持输出元字段
<不< < > ><不< < > ><不< < > ><不< < > > 马里亚行 <不< < > >受限制,相交,有懔edge懔degree,并且不支持筛选器 有限,不支持输出元字段
<不< < > ><不< < > ><不< < > ><不< < > > 配置sqlalchemy
{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
0
{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
1
端到端SQL示例
{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
2
配置SQL数据库以匹配GraphQL架构
animal_table
的表,它有一个列
称为动物名。如果所需的模式具有类型{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
0
{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
4
animal
视图进行编译。其他
漂亮的图形打印查询
{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
5
json.tool
为模型,从stdin读取并写入stdout。展开顶点字段
@可选的
指令不展开
任何顶点域。
例如:{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
6
match
当前允许任意遍历的最后一步是可选的。
因此,上述graphql的等效
match
遍历如下:{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
7
@可选的
指令的顶点,该指令确实展开
其中的顶点场。
例如:
{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
8
match
查询来表示。
具体来说,以下是一个有效的match
语句,
因为可选的遍历遵循另一条边:{
Person {
out_Person_Knows @optional {
name @filter(op_name: "=", value: ["$name"])
}
name @output(out_name: "person_name")
}
}
9
unionall
)表示一个可选的复合
匹配
查询。例如,上面的graphql
查询可以表示如下:{"name":"Charles"}
0
$match1
和$match2
中的select
语句,
但它说明了总体思路。性能惩罚
匹配
查询的并集。
具体来说,对于
n
复合选项,我们生成2个n不同的匹配查询。
对于
n可选边的2个子集
s
中的每一个子集:s
中每个遍历的@可选限制。
s
的补码中的每个遍历t
,我们完全放弃t
以及其中的所有顶点和指令,我们添加了一个过滤器
在上一次遍历中,以确保与t
相对应的边不存在。@的可能子集
可以同时满足的语句。
可选的
类型等效提示
参数类型
从另一个类型
继承,只允许实现接口
{"name":"Charles"}
1
类型等价提示值应该是
{animal:animalcatdog}
。
这使编译器知道animalcatdog
union类型隐式等价于
animal
类型,因为在数据库模式中没有其他类型从animal
继承。
这允许编译器在gremlin中执行精确的类型强制,并优化
如果强制转换为
工会的同等类型。类型等效提示{animal:animalcatdog}
。
将允许在foo的
相邻动物的
顶点字段上使用
@fold
:{"name":"Charles"}
2
图表
schemagraph
构建graphql模式。架构图
底层数据库模式的表示,但它有三个主要优点,使其成为
更强大的模式内省工具:
get_subclass_set
,这些函数使探索变得更容易
架构。schemagraph的模拟示例,请参见下面的内容:
{"name":"Charles"}
3
generation。我们还计划
添加一种机制,可以在其中使用graphql查询schemagraph
cypher查询参数
graphql_to_redisgraph_cypher
函数。但是,对于neo4j,我们可以使用neo4j的客户机
参数插值本身,这样我们就不会重新发明轮子。在查询中插入参数
这里足够细粒度——对于cypher后端,我们只希望在后端
是重新发现,但如果是Neo4J就不行。
neo4j_client的neo4j python客户机
{"name":"Charles"}
4
修改已解析的自定义标量类型
{"name":"Charles"}
5
FAQ
许可证
推荐PyPI第三方库