使用 Python 创建查询语言
Create a Query language using Python
我正在研究类似弹性搜索的搜索服务器。只是我正在开发的一个小项目。已完成大部分部分,但仍停留在用户与系统交互的方式上。
我最初决定用户将通过发送包含必填字段及其值的 JSON 查询来请求。但我面临的问题是,即使我可以使用 json 方式评估查询,我也无法实现布尔查询和 Compounf 语句。
我正在尝试类似
index: name
schema:name
field1: value
field 2: value
但如果实现布尔表达式也可以是这样的
index : name
schema : name
field 1 : name1 or name 2
field 2: <9.22 and >=2.32
field 3: (<9.22 and >=2.32) or (<100 and >90) // compound statement.
是否有某种直接的方法来实现这一点,而无需实际创建查询语言语法。如果是,那我该如何实现,如果不是,那也是同样的事情。
我正在考虑基于每个字段的和/或拆分值,但如果有复合语句,那将行不通。
我也在检查 pyparsing,但我想不出一个有效的方法来使用它。
当然可以。这是一个仅使用 JSON.
的示例
对于基本的单字段查询,使用映射:
{"fieldname": {"op": "=", "value": "somevalue"}}
对于复合查询,执行如下操作:
{"and": [
{"field": {"op": "=", "value": "somevalue"}},
{"field2": {"op": ">", "value": 9.22}},
]}
对于复杂的查询,如您的示例所示:
{
"and": [
{
"index": {
"op": "=",
"value": "name"
}
},
{
"schema": {
"op": "=",
"value": "name"
}
},
{
"or": [
{
"field1": {
"op": "=",
"value": "name1"
}
},
{
"field1": {
"op": "=",
"value": "name2"
}
}
]
},
{
"or": [
{
"field2": {
"op": "<",
"value": 9.22
}
},
{
"field2": {
"op": ">=",
"value": 2.32
}
}
]
},
{
"or": [
{
"or": [
{
"field3": {
"op": "<",
"value": 9.22
}
},
{
"field3": {
"op": ">=",
"value": 2.32
}
}
]
},
{
"or": [
{
"field3": {
"op": "<",
"value": 100
}
},
{
"field3": {
"op": ">",
"value": 90
}
}
]
}
]
}
]
}
真正的问题是您的复合语句会变得多复杂,它们是否只包含 AND 和 OR 关键字。据我所知,你最好为此定义一个合适的语法,而不是仅仅使用正则表达式的组合来完成工作(尽管语法本质上就是这样)。
我建议使用 parsely,您可以在其中清楚地定义 lex 格式的语法并为您生成解析器。这样您就可以更好地标记事物并在调试时有更好的理解。
我正在研究类似弹性搜索的搜索服务器。只是我正在开发的一个小项目。已完成大部分部分,但仍停留在用户与系统交互的方式上。
我最初决定用户将通过发送包含必填字段及其值的 JSON 查询来请求。但我面临的问题是,即使我可以使用 json 方式评估查询,我也无法实现布尔查询和 Compounf 语句。
我正在尝试类似
index: name
schema:name
field1: value
field 2: value
但如果实现布尔表达式也可以是这样的
index : name
schema : name
field 1 : name1 or name 2
field 2: <9.22 and >=2.32
field 3: (<9.22 and >=2.32) or (<100 and >90) // compound statement.
是否有某种直接的方法来实现这一点,而无需实际创建查询语言语法。如果是,那我该如何实现,如果不是,那也是同样的事情。
我正在考虑基于每个字段的和/或拆分值,但如果有复合语句,那将行不通。
我也在检查 pyparsing,但我想不出一个有效的方法来使用它。
当然可以。这是一个仅使用 JSON.
的示例对于基本的单字段查询,使用映射:
{"fieldname": {"op": "=", "value": "somevalue"}}
对于复合查询,执行如下操作:
{"and": [
{"field": {"op": "=", "value": "somevalue"}},
{"field2": {"op": ">", "value": 9.22}},
]}
对于复杂的查询,如您的示例所示:
{
"and": [
{
"index": {
"op": "=",
"value": "name"
}
},
{
"schema": {
"op": "=",
"value": "name"
}
},
{
"or": [
{
"field1": {
"op": "=",
"value": "name1"
}
},
{
"field1": {
"op": "=",
"value": "name2"
}
}
]
},
{
"or": [
{
"field2": {
"op": "<",
"value": 9.22
}
},
{
"field2": {
"op": ">=",
"value": 2.32
}
}
]
},
{
"or": [
{
"or": [
{
"field3": {
"op": "<",
"value": 9.22
}
},
{
"field3": {
"op": ">=",
"value": 2.32
}
}
]
},
{
"or": [
{
"field3": {
"op": "<",
"value": 100
}
},
{
"field3": {
"op": ">",
"value": 90
}
}
]
}
]
}
]
}
真正的问题是您的复合语句会变得多复杂,它们是否只包含 AND 和 OR 关键字。据我所知,你最好为此定义一个合适的语法,而不是仅仅使用正则表达式的组合来完成工作(尽管语法本质上就是这样)。
我建议使用 parsely,您可以在其中清楚地定义 lex 格式的语法并为您生成解析器。这样您就可以更好地标记事物并在调试时有更好的理解。