当前位置: 首页 > 知识库问答 >
问题:

如何使用multi_match、boosting、通配符和filter连接ElasticSearch查询?

唐照
2023-03-14

我在努力实现这个目标:

  1. 通过bool查询筛选出结果,如“status=1”
  2. 通过布尔范围查询筛选出结果,如“discance:gte 10和lte 60”
  3. 通过从int数组中匹配至少一个int值筛选出结果
  4. 在多个字段中搜索单词,并计算文档得分。有些字段需要通配符,有些字段需要增强,如ImportantField^2、SomeField*、SomeOtherField^0.75
  5. 以上所有点都由AND运算符联接。一个点中的所有术语由OR运算符联接。

现在我写了类似的东西,但是通配符不起作用。搜索“abc”在“name”字段中没有找到“abcd”。这怎么解决?

{
  "filtered": {
    "query": {
      "multi_match": {
        "query": "John Doe",
        "fields": [
          "*name*^1.75",
          "someObject.name",
          "tagsArray",
          "*description*",
          "ownerName"
        ]
      }
    },
    "filter": {
      "bool": {
        "must": [
          {
            "term": {
              "status": 2
            }
          },
          {
            "bool": {
              "should": [
                {
                  "term": {
                    "someIntsArray": 1
                  }
                },
                {
                  "term": {
                    "someIntsArray": 5
                  }
                }
              ]
            }
          },
          {
            "range": {
              "distanceA": {
                "lte": 100
              }
            }
          },
          {
            "range": {
              "distanceB": {
                "gte": 50,
                "lte": 100
              }
            }
          }
        ]
      }
    }
  }
}

映射:

{
  "documentId": {
    "type": "integer"
  },
  "ownerName": {
    "type": "string",
    "index": "not_analyzed"
  },
  "description": {
    "type": "string"
  },
  "status": {
    "type": "byte"
  },
  "distanceA": {
    "type": "short"
  },
  "createdAt": {
    "type": "date",
    "format": "yyyy-MM-dd HH:mm:ss"
  },
  "distanceB": {
    "type": "short"
  },
  "someObject": {
    "properties": {
      "someObject_id": {
        "type": "integer"
      },
      "name": {
        "type": "string",
        "index": "not_analyzed"
      }
    }
  },
  "someIntsArray": {
    "type": "integer"
  },
  "tags": {
    "type": "string",
    "index": "not_analyzed"
  }
}

共有1个答案

轩辕鸿祯
2023-03-14

如果希望为多个字段应用通配符,并同时为单个字段应用各种提升值,则可以使用查询字符串:

以下是您的查询方式:

POST <your_index_name>/_search
{  
   "query":{  
      "bool":{  
         "must":[  
            {  
               "query_string":{  
                  "query":"abc*",
                  "fields":[  
                     "*name*^1.75",
                     "someObject.name",
                     "tagsArray",
                     "*description*",
                     "ownerName"
                  ]
               }
            }
         ],
         "filter":{  
            "bool":{  
               "must":[  
                  {  
                     "term":{  
                        "status":"2"
                     }
                  },
                  {  
                     "bool":{  
                        "minimum_should_match":1,
                        "should":[  
                           {  
                              "term":{  
                                 "someIntsArray":1
                              }
                           },
                           {  
                              "term":{  
                                 "someIntsArray":5
                              }
                           }
                        ]
                     }
                  },
                  {  
                     "range":{  
                        "distanceA":{  
                           "lte":100
                        }
                     }
                  },
                  {  
                     "range":{  
                        "distanceB":{  
                           "gte": 50,
                           "lte":100
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}

请注意,对于字段someintsarray,我使用了“minimum_should_match”:1,这样您就不会得到这两个值都没有的文档。

更新的答案:

根据更新后的注释,您可以使用带有通配符搜索的字段由query_string使用,并且可以使用带有boosting的简单匹配查询,如下所示。在组合shoul子句中包含这两个查询(根据您的需求,甚至可以添加更多匹配查询)。这样,您就可以控制在哪里可以使用通配符查询,在哪里不可以使用通配符查询。

{  
   "query":{  
      "bool":{  
         "should":[  
            {  
               "query_string":{  
                  "query":"joh*",
                  "fields":[  
                     "name^2"
                  ]
               }
            },
            {  
               "match":{  
                  "description":{  
                     "query":"john",
                     "boost":15
                  }
               }
            }
         ],
         "filter":{  
            "bool":{  
               "must":[  
                  {  
                     "term":{  
                        "status":"2"
                     }
                  },
                  {  
                     "bool":{  
                        "minimum_should_match":1,
                        "should":[  
                           {  
                              "term":{  
                                 "someIntsArray":1
                              }
                           },
                           {  
                              "term":{  
                                 "someIntsArray":5
                              }
                           }
                        ]
                     }
                  },
                  {  
                     "range":{  
                        "distanceA":{  
                           "lte":100
                        }
                     }
                  },
                  {  
                     "range":{  
                        "distanceB":{  
                           "lte":100
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}

如果有帮助请告诉我

 类似资料:
  • 问题内容: 我有一个具有属性名称和姓氏的用户对象。我想使用一个查询来搜索这些字段,并且在文档中找到了该字段,但是我不知道如何将其与通配符一起正确使用。可能吗? 我尝试了查询,但没有成功: 问题答案: 或者,您可以对通配符使用查询。 这将比在索引时使用nGram过滤器慢(请参阅我的其他答案),但是如果您正在寻找一种快速且肮脏的解决方案… 我也不确定您的映射,但是如果您使用而不是映射,则需要如下所示:

  • 该字段中的映射是: 所以,我想我误解了通配符在ES中是如何工作的。有人知道为什么不匹配文本字段中的“任何字符”吗? 谢了。 > 创建索引

  • 问题内容: 我很难用Elasticsearch构建查询。 我想查询类似的东西: 所以我试图构造的是这样的: 但这似乎返回一个错误。 谁能给我一个指针,我应该如何看待用Elasticsearch进行这种OR查询? 我当前的数据已发送: 和我的查询: 返回此错误: 问题答案: 这是由于JSON格式错误所致。此查询的正确JSON格式如下-

  • 我使用ES7.1,我想使用多匹配查询从几个字段获取结果,但我想在特定的字段上使用match_prace获取结果。 我尝试了很多东西,这是最接近我想要的版本: 我得到一个错误: parsing_exception“,”reason“:”[multi_match]格式错误的查询,应为[END_OBJECT],但找到[FIELD_NAME] 有没有办法把这两个标准结合起来?我不想创建2个查询。

  • 问题内容: 我如何询问我的Elasticsearch服务器目前有多少个连接打开? 这和插座数一样吗?(我也不知道如何获得这些数字) 这与客户端的数量不同,对,因为每个客户端都可以打开多个连接? 虽然我确实发现您可以在Elasticsearch客户端上为每个客户端指定一个maxSockets,但找不到任何信息:https ://www.elastic.co/guide/en/elasticsearc

  • 在ElasticSearch7.x中,我使用一个具有同义词过滤器的分析器对数据字段进行了索引。但是,为了支持增强“完全”匹配数据字段中的查询词的查询,而不是匹配数据中的同义词的查询,我将使用。 为此,对于我想要精确匹配的查询,我想提供一个在其中没有同义词过滤器的分析器。这可以通过来完成。但是,我的主要查询是查询,用于在所有需要的字段上搜索这些术语(并且具有不同的重要性(boosting))。 似乎