Elasticsearch查询非严格地从不同领域搜索

Elasticsearch query to search from different fields non-strictly

我是 elasticsearch 的新手,一直在 python 中使用 elasticsearch。我所拥有的是人们的 csv 格式数据,我已将其转换为 json 并添加到 elasticsearch 索引中。 字段如下:

'Last Name (Legal Name)', 
'First Name', 
'Middle Name', 
'Other Last Name', 
'Business Mailing Address City Name', 
'Business Mailing Address State Name',
'Business Practice Location Address City Name', 
'Business Practice Location Address State Name', 
'Authorized Official Last Name', 
'Authorized Official First Name', 
'Authorized Official Middle Name', 
'Authorized Official Title or Position'

我想在查询中输入的内容类似于 "Name City"。例如,"Clinton Adams Hamilton" 其中 Clinton Adams 是姓名,Hamilton 是城市。在大多数情况下,我不确定哪个是名字或哪个是姓氏,因此我需要匹配所有字段。

我目前使用的是这样的:

"query":{
                "query_string":{
                    "fields": ['Last Name (Legal Name)', 'First Name', 'Middle Name', 
                             'Other Last Name', 'Business Mailing Address City Name', 
                             'Business Mailing Address State Name',
                             'Business Practice Location Address City Name', 'Business Practice                            
                              Location Address State Name', 
                             'Authorized Official Last Name', 'Authorized Official First Name', 
                             'Authorized Official Middle Name', 
                             'Authorized Official Title or Position'],
                    "query": "(Clinton) AND (Adams) AND (Hamilton)",
                    }
                }

如果我从数据库中搜索确切的姓名和城市,则以下查询工作正常,但如果我的姓名有拼写错误,或者如果某个姓名中的名字是缩写,则它不会给出预期的结果.例如,如果查询类似于 "Clinton A Hamilton",则它不会与任何文档匹配。我不能使用 OR 运算符,因为有多个人的名字相似,所以查询的所有部分 - 第一个 name/last 名字和城市都很重要。我希望查询从索引中获取最相关的记录。

我尽力解释了情况。无论如何,请随时询问是否有任何不清楚的地方。感谢您的建议。谢谢

首先,您应该尝试多匹配查询,尤其是适合您用例的 cross_field 类型。 Documentation here.

它将您搜索的所有字段作为一个混合字段处理。

但是,如果您保留运算符 "AND",则对 "Clinton A Hamilton" 的查询将不会匹配 "Clinton Adams / Hamilton" 文档。 我认为您应该选择标准的 OR 运算符。它会给你第一个相关文件的第一个位置。先完全匹配,后部分匹配。

如果您确定您的许多用户将使用小写形式作为名字,您应该考虑创建一个特殊的分析器来索引小写形式。

这是独立索引中的示例:

PUT diminutive
{
  "settings": {
    "analysis": {
      "filter": {
        "diminutive": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 3
        }
      }, 
      "analyzer": {
        "diminutive": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding",
            "diminutive"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "firstname": {
        "type": "text",
        "analyzer": "diminutive",
        "search_analyzer": "standard"
      }
    }
  }
}

然后您可以在 'First Name' 的字段中使用小型分析器(请参阅文档 here)并在多匹配查询中添加子字段。

可能需要处理很多信息/概念,但我认为这应该是您用例的良好开端。

我要做的第一件事是完善您的文档映射。特别是,我会考虑保留这么多不同的与名称相关的字段(例如,名字、姓氏、中间名、官方授权...)是否有意义,或者过滤一些并合并是否有意义别的东西。例如,此文档映射对您有意义吗?

{
  'name', 
  'business_mailing': {
    'city',
    'state'
  },
  'business_practice_location': {
    'city',
    'state'
  }
}

要点是,您应该根据您希望 运行 对其进行的查询来优化您的数据。

使用上面的映射,然后您可以 运行 配置 boolean query (a must) that contains two match queries, possibly with the fuzzyness option 以解决拼写错误。例如,

{
  'query': {
    'bool': {
      'must': [{
        'match': {
          'name': { 'query': 'Clinton Adams', 'fuzzyness': 'AUTO'
        }
      },{
        'match': {
          'business_mailing': { 'query': 'Hamilton', 'fuzzyness': 'AUTO'
        }
      }]
    }
  }
}

另一个解决方案可能是使用 copy_to 映射选项并定义一个新的可查询字段,其中包括名称字段和城市字段的值。这是文档 https://www.elastic.co/guide/en/elasticsearch/reference/7.5/copy-to.html

的 link