将中缀表达式转换为弹性搜索查询

时间:2018-12-31 08:18:46

标签: php algorithm elasticsearch

如何将中缀表达式转换为弹性搜索查询
我的运营商是! + *
用户可以使用这些运算符进行任何表达,例如:
(((A*B*(!C))*(D*E))+F)*G
我希望在弹性搜索中将其转换为bool query

修改
我不知道为什么我不早说这个,但是我已经写了一个代码将中缀转换成后缀表达式,然后我调用了一个非常脏的递归方法来创建should (+), must (*) and must_not (!),但是我想要的是为我做花招的最佳方法。

我最后的查询是这样的,我认为这很讨厌:

{
  "from": 0,
  "size": 10,
  "_source": [
    "*"
  ],
  "index": "insta_userpost_new2",
  "body": {
    "query": {
      "bool": {
        "must": [
          {
            "match_phrase": {
              "caption.text": "G"
            }
          },
          {
            "bool": {
              "should": [
                {
                  "match_phrase": {
                    "caption.text": "F"
                  }
                },
                {
                  "bool": {
                    "must": [
                      {
                        "bool": {
                          "must": [
                            {
                              "match_phrase": {
                                "caption.text": "E"
                              }
                            },
                            {
                              "match_phrase": {
                                "caption.text": "D"
                              }
                            }
                          ]
                        }
                      },
                      {
                        "bool": {
                          "must": [
                            {
                              "bool": {
                                "must_not": [
                                  {
                                    "match_phrase": {
                                      "caption.text": "C"
                                    }
                                  },
                                  {
                                    "bool": {
                                      "must": [
                                        {
                                          "match_phrase": {
                                            "caption.text": "B"
                                          }
                                        },
                                        {
                                          "match_phrase": {
                                            "caption.text": "A"
                                          }
                                        }
                                      ]
                                    }
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        ]
      }
    }
  }
}

3 个答案:

答案 0 :(得分:1)

我可能会尝试利用simply_query_string。为此,您必须:

  • +替换为|(对于OR
  • 然后将*替换为+(对于AND
  • 最后将!替换为-(对于NOT

因此,如果用户输入以下内容:

(((A*B*(!C))*(D*E))+F)*G

你最终会得到这个

(((A+B+(-C))+(D+E))|F)+G

这是一个布尔表达式,可以直接在simply_query_string查询中使用。

GET /_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content"],
            "query" : "(((A+B+(-C))+(D+E))|F)+G"
        }
    }
}

答案 1 :(得分:0)

您可以在查询中使用Elasticsearch脚本,如下所示: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html

脚本选项很少,最简单,最棘手的是“无痛”脚本。从弹性文档中:

  

在Kibana中定义脚本字段时,可以选择脚本语言。从5.0开始,默认选项是Lucene表达式和Painless

还可以使用“脚本字段”返回计算结果: https://www.elastic.co/guide/en/kibana/current/scripted-fields.html

答案 2 :(得分:0)

您可以运行中缀表达式评估[1],并用DSL bool查询作曲家替换标准的eval操作。

实际上,我们为https://opensource.appbase.io/mirage/做了类似的事情(您可以尝试使用),在那里我们将GUI块映射到可组合的布尔查询。可以在https://github.com/appbaseio/mirage上查看源代码。

[1]参考:https://www.geeksforgeeks.org/expression-evaluation/