ElasticSearch查询,可从不同字段进行非严格搜索

6yoyoihd  于 2023-03-17  发布在  ElasticSearch
关注(0)|答案(2)|浏览(146)

我对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亚当斯汉密尔顿”,其中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汉密尔顿”,它就不会与任何文档匹配。我不能使用OR运算符,因为有多个人具有相似的姓名。所以查询的所有部分-名字/姓氏和城市都很重要。我希望查询从索引中获取最相关的记录。
我已经尽了最大的努力来解释这个情况。无论如何,如果有什么不太清楚的地方,请尽管问。谢谢你的建议。

ldfqzlk8

ldfqzlk81#

我要做的第一件事是优化您的文档Map。特别是,我会考虑保留这么多不同的与姓名相关的字段(例如,名、姓、中间名、官方授权...)是否有意义,或者过滤一些字段并合并其他字段是否有意义。例如,这种文档Map对您有意义吗?

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

关键是,您应该根据要对数据运行的查询来优化数据。
有了上面的Map,您就可以运行一个包含两个match查询的boolean query(一个must),其中可能配置了fuzzyness选项以解决输入错误。

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

另一种解决方案是使用copy_toMap选项并定义一个新的可查询字段,其中包含name字段和city字段的值。

elcex8rz

elcex8rz2#

首先,你应该给予一下多重匹配查询,特别是适合你的用例的cross_field类型。
它将处理您所有的搜索字段作为一个混合字段。
但是如果你保留“AND”运算符,那么查询“Clinton A汉密尔顿”将与“Clinton亚当斯/ 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),并在多匹配查询中添加子字段。
这可能需要处理大量的信息/概念,但我认为这应该是您的用例的一个良好开端。

相关问题