是否可以在脚本字段中访问查询词?

Posted

技术标签:

【中文标题】是否可以在脚本字段中访问查询词?【英文标题】:Is it possible to access a query term in a script field? 【发布时间】:2021-04-13 08:11:31 【问题描述】:

我想构建一个弹性搜索查询,我可以在其中搜索一个术语并为每个找到的文档即时计算一个新字段,该字段是根据一些现有字段以及查询术语计算的。这可能吗?

例如,假设在我的 EL 查询中,我正在搜索“text”字段中包含关键字“amsterdam”的文档。

"filter": [
        
          "match_phrase": 
            "text": 
              "query": "amsterdam"
            
          
        ]

现在我还想在我的查询中有一个脚本字段,它根据其他字段以及查询计算一些值。 到目前为止,我只发现了如何访问文档的其他字段,例如使用 doc['someOtherField']

 "script_fields" : 
        "new_field" : 
            "script" : 
                "lang": "painless",
                "source": "if (doc['citizens'].value > 10000)  
                           return "large";
                           
                           return "small";"
            
        
   

如何整合查询词,例如如果我想在 if 语句中添加“如果查询词以 a-e 开头”?

【问题讨论】:

【参考方案1】:

您在正确的轨道上,但 script_fields 主要用于对文档的属性进行后处理 - 它们不会帮助您过滤任何文档,因为它们是在查询之后运行的阶段。

话虽如此,您可以使用脚本通过script queries 过滤您的文档。不过,在您这样做之前,您应该探索替代方案。

换句话说,当所有其他机制和技术都用尽时,应该使用脚本。

回到你的例子。我想到了三种可能性。

    Match phrase prefix queries 作为一组 bool-should 子查询:
POST your-index/_search

  "query": 
    "bool": 
      "must": [
        
          "bool": 
            "should": [
              
                "match_phrase_prefix": 
                  "text_field": "a"
                
              ,
              
                "match_phrase_prefix": 
                  "text_field": "b"
                
              ,
              
                "match_phrase_prefix": 
                  "text_field": "c"
                
              ,
              ... till the letter "e"
            ]
          
        
      ]
    
  

    regexp 查询:
POST your-index/_search

  "query": 
    "bool": 
     "must": [
       
         "regexp": 
           "text_field": "[a-e].+"
         
       
     ] 
    
  

    使用.charAt比较的脚本查询:
POST your-index/_search

  "query": 
    "bool": 
      "must": [
        
          "script": 
            "script": 
              "source": """
                char c = doc['text_field.keyword'].value.charAt(0);
                return c >= params.gte.charAt(0) && c <= params.lte.charAt(0);
              """,
              "params": 
                "gte": "a",
                "lte": "e"
              
            
          
        
      ]
    
  


如果您对 ES 比较陌生并且希望看到真实世界的示例,请查看我最近发布的 Elasticsearch Handbook。一章专门介绍脚本,事实证明,您可以通过脚本实现很多(当然,如果执行得当的话)。

【讨论】:

谢谢,这已经澄清了一点。不过,我实际上确实想进行后期处理。我真正想要的是一个动态字段,其值仅在执行查询后才计算,因为该字段需要查询进行计算。因此,如果我的查询(匹配短语)是“amsterdam”,我想获取所有满足此查询的文档。然后对于这些文档中的每一个,动态字段是否根据某些脚本填充了一个值,该脚本考虑了查询“amsterdam”以及其他(静态)文档字段。 但这也适用于任何其他查询词,因此继续我的示例,如果查询词恰好是“amsterdam”,那么每个文档的动态字段(匹配“amsterdam”)如果文档的公民> 10000,则值为“大”,否则为“小”。如果查询词恰好是“london”,那么永远返回 doc(匹配“london”),动态字段将只是“small”(因为查询词“london”不以 a-e 开头)。 明白了。好的脚本字段将支持我的第三个示例中的语法,并添加了params['_source'],这在标准脚本查询中被禁用。如果这能让您进一步了解您的解决方案,或者您需要更多信息,请告诉我。 我不确定我是否理解 params[_source] 如何帮助我...据我了解 params[_source] 让我可以访问类似于 doc[] 的文档的字段,只是它也适用于复杂类型的字段。我想访问的不是文档中的字段,而是我的搜索查询中的查询词,所以我想访问 filter.query_term.text。知道这是否可能吗? 哦,我明白了。不,那是不可能的。但是您可以在构建query 时通过"params" 提供它。

以上是关于是否可以在脚本字段中访问查询词?的主要内容,如果未能解决你的问题,请参考以下文章

如何在通过 255 字段限制的访问中组合表?

访问:最少超过 255 个字符

有没有办法在文本字段表达式中访问SQL查询结果,以有条件地在标题带中显示它?

在备忘录访问中插入查询

mysql多个字段模糊查询是否包含某个词

mysql多个字段模糊查询是否包含某个词