【问题标题】:Elasticsearch minhash prefix query with wildcards?带有通配符的 Elasticsearch minhash 前缀查询?
【发布时间】:2019-03-28 11:35:54
【问题描述】:

我为某些文本生成了一个 minhash 字段(基于 minhash 算法),现在我的问题是,是否可以用通配符以某种方式补充或添加前缀查询?因为问题是,散列字符串值基于带状疱疹/令牌的内容(文本)位置。所以前几个字符(前缀)可能并不总是完全匹配相似的内容。是否可以在查询前缀前添加通配符,例如 *3AF8659GJ?

编辑:我想我对这个问题的思考不够认真。散列差异可以在散列字符串中的任何位置(基于文本差异的内容位置的文本差异)。所以我猜“最好”的唯一方法是编辑距离和一些阈值。

例如,将所有散列放入一个数组并按词法顺序对它们进行排序(或者如何对十六进制字符串进行排序?),然后您只比较接下来的 k 个文档,直到达到编辑距离阈值,然后将重复项放入一个单独的数组..

【问题讨论】:

  • 那么,你的想法是只比较一个后缀?如果是,您准备好重新索引您的数据了吗?
  • 请看我下面的评论,我想先比较前缀,但可能会出现文本差异不仅出现在开头,还可能出现在结尾或任何地方,所以我猜编辑距离是最好的方法。但是模糊搜索只有 2 个编辑距离是荒谬的。我必须根据编辑距离在 Node.js 中实现自定义搜索..

标签: elasticsearch wildcard prefix minhash


【解决方案1】:

出于性能原因,强烈建议不要按后缀搜索,如 official document 中所述:

为了防止非常慢的通配符查询,通配符项不应以通配符 * 或 ? 之一开头。

仍然有一种方法可以通过使用精巧的分析器来实现您的目标。这个想法是只索引 minhash 的结尾。您可以按如下所述实现。

首先,使用以下分析器创建索引:

PUT minhash-index
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "suffix": {
            "type": "custom",
            "tokenizer": "keyword",
            "filter": [
              "lowercase",
              "reverse",
              "substring",
              "reverse"
            ]
          }
        },
        "filter": {
          "substring": {
            "type": "edgeNGram",
            "min_gram": 1,
            "max_gram": 10
          }
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "minhash": {
          "type": "text",
          "analyzer": "suffix",
          "search_analyzer": "standard"
        }
      }
    }
  }
}

suffix 分析器的想法是,它将为您投入索引的每个 minhash 索引长度为 1 到 10 的所有后缀(您可以决定索引更长的后缀)。

例如,对于 minhash C50FD711C2C43287351892A4D82F44B055F048C46D2C54197AC1D1E921F11E6699C4057C4B93907518E6DCA51A672D3D3E419160DAE276CB7716D11B94D8C3BB2E4A591329B7AF973D17A7F9336342FFAAFD4D,它将索引以下所有后缀:

  • d
  • 4d
  • d4d
  • fd4d
  • afd4d
  • aafd4d
  • faffd4d
  • ffaafd4d
  • 2ffaafd4d
  • 42ffaafd4d

然后你可以很容易地通过以下查询搜索并找到上面的minhash:

POST minhash-index/_search
{
  "query": {
    "match": {
      "minhash": "42FFAAFD4D"
    }
  }
}

【讨论】:

  • 非常感谢这是一个不错的方法,但问题是,无法根据 2 个文档的内容提前确定差异/相似之处在哪里。单个十六进制散列的 minhash 散列键位置简单地连接在一起,它们是根据文本的 shingles 计算的。因此,它取决于散列键差异所在的文本内容位置的差异。它可以在开头或结尾或中间的某个地方。另一种方法是文档与其他文档相比的编辑距离。
  • 因此,我正在考虑另一种方法,我首先提取所有文档并将它们放入一个数组中。然后我以 minhash 排序顺序对文档进行排序,并根据一些编辑距离仅比较接下来的 k 个文档以检测重复项...
猜你喜欢
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-15
相关资源
最近更新 更多