【问题标题】:Index on Elastic search contains and starts with search弹性搜索索引包含并以搜索开头
【发布时间】:2021-03-11 06:41:17
【问题描述】:

我们正在使用弹性搜索来更快地搜索我们的组织数据。数据模型有组织id、地址、组织名称、业务开始日期和组织联系人数组。
我们已要求执行包含搜索的字符串,并且字符串以搜索组织 ID 和/或组织名称字段开头 例如, organization.name:”abc*” or organization.id:”abc

organization.name:”abc*” and organization.id:”*abc*”
organization.name:”*abc*” and organization.id:”abc*”
由于我们需要在同一字段上同时使用 Ngram 分析器,因此无法正常工作 请指教

【问题讨论】:

  • @arpuc 你能分享一些示例索引数据和预期的搜索结果吗?

标签: java elasticsearch elastic-stack elasticsearch-dsl elasticsearch-query


【解决方案1】:

据我所知,您需要找到那些文件,其中organization.nameabc 开头并且organization.id 包含abc(不是开头)。

为此,您可以使用multi-field,这对于以不同方式为不同目的索引同一字段以及n-gram tokenizer 很有用

添加一个包含索引数据、映射、搜索查询和搜索结果的工作示例

索引映射:

    {
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 20,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    },
    "max_ngram_diff": 20
  },
  "mappings": {
    "properties": {
      "organization": {
        "properties": {
          "name": {
            "type": "keyword",
            "fields": {
              "raw": {
                "type": "text",
                "analyzer": "my_analyzer"
              }
            }
          },
          "id": {
            "type": "keyword",
            "fields": {
              "raw": {
                "type": "text",
                "analyzer": "my_analyzer"
              }
            }
          }
        }
      }
    }
  }
}

索引数据:

{
  "organization": {
    "id": "abc def",
    "name": "Aspect abc Technology"
  }
}
{
  "organization": {
    "id": "defabc",
    "name": "abc Aspect Technology"
  }
}
{
  "organization": {
    "id": "abcef",
    "name": "abc Aspect Technology"
  }
}
{
  "organization": {
    "id": "abc",
    "name": "Aspect Technology"
  }
}

搜索查询:

{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "match": {
                  "organization.id.raw": "abc"
                }
              },
              {
                "prefix": {
                  "organization.name": "abc"
                }
              }
            ],
            "must_not": {
              "prefix": {
                "organization.id": "abc"
              }
            }
          }
        },
        {
          "bool": {
            "must": [
              {
                "prefix": {
                  "organization.id": "abc"
                }
              },
              {
                "match": {
                  "organization.name.raw": "abc"
                }
              }
            ],
            "must_not": {
              "prefix": {
                "organization.name": "abc"
              }
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

搜索结果:

"hits": [
      {
        "_index": "65054994",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.3590312,
        "_source": {
          "organization": {
            "id": "abc def",
            "name": "Aspect abc Technology"
          }
        }
      },
      {
        "_index": "65054994",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0725547,
        "_source": {
          "organization": {
            "id": "defabc",
            "name": "abc Aspect Technology"
          }
        }
      }
    ]

【讨论】:

  • @arupc 你有机会看我的回答吗,期待得到你的反馈?
  • 非常感谢,这个答案听起来很有希望,会检查并确认。按照你在这里的解释,我相信它会成功的。
  • 请注意,organization.name 以 abc 开头,并且 organization.id 包含 abc(不是开头)——反之亦然。这意味着,organization.id 以 abc 开头,并且 organization.name 包含 abc(不是开头)
  • 是的@arupc,我在上面的查询中都包含了这两种情况
  • 是的,这种方法很有效,我已将所有 DSL 查询转换为 Lucene 查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多