【问题标题】:Extract keywords (multi word) from text using elastic search使用弹性搜索从文本中提取关键字(多词)
【发布时间】:2016-10-04 21:47:13
【问题描述】:

我有一个充满关键字的索引,我想根据这些关键字从输入文本中提取关键字。

以下是示例关键字索引。请注意,关键字也可以是多个单词,或者基本上它们是唯一的标签。

{
  "hits": {
    "total": 2000,
    "hits": [
      {
        "id": 1,
        "keyword": "thousand eyes"
      },
      {
        "id": 2,
        "keyword": "facebook"
      },
      {
        "id": 3,
        "keyword": "superdoc"
      },
      {
        "id": 4,
        "keyword": "quora"
      },
      {
        "id": 5,
        "keyword": "your story"
      },
      {
        "id": 6,
        "keyword": "Surgery"
      },
      {
        "id": 7,
        "keyword": "lending club"
      },
      {
        "id": 8,
        "keyword": "ad roll"
      },
      {
        "id": 9,
        "keyword": "the honest company"
      },
      {
        "id": 10,
        "keyword": "Draft kings"
      }
    ]
  }
}

现在,如果我输入文本为 “我在 facebook 上看到了 Lending club 的新闻,你的故事和 quora” 搜索的输出应该是 ["lending club", “facebook”、“你的故事”、“quora”]。此外,搜索应该不区分大小写

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    只有一种真正的方法可以做到这一点。您必须将您的数据索引为关键字并使用 shingles 进行搜索:

    查看此复制:

    首先,我们将创建两个自定义分析器:关键字和带状疱疹:

    PUT test
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "my_analyzer_keyword": {
              "type": "custom",
              "tokenizer": "keyword",
              "filter": [
                "asciifolding",
                "lowercase"
              ]
            },
            "my_analyzer_shingle": {
              "type": "custom",
              "tokenizer": "standard",
              "filter": [
                "asciifolding",
                "lowercase",
                "shingle"
              ]
            }
          }
        }
      },
      "mappings": {
        "your_type": {
          "properties": {
            "keyword": {
              "type": "string",
              "index_analyzer": "my_analyzer_keyword",
              "search_analyzer": "my_analyzer_shingle"
            }
          }
        }
      }
    }
    

    现在让我们使用您提供的内容创建一些示例数据:

    POST /test/your_type/1
    {
      "id": 1,
      "keyword": "thousand eyes"
    }
    POST /test/your_type/2
    {
      "id": 2,
      "keyword": "facebook"
    }
    POST /test/your_type/3
    {
      "id": 3,
      "keyword": "superdoc"
    }
    POST /test/your_type/4
    {
      "id": 4,
      "keyword": "quora"
    }
    POST /test/your_type/5
    {
      "id": 5,
      "keyword": "your story"
    }
    POST /test/your_type/6
    {
      "id": 6,
      "keyword": "Surgery"
    }
    POST /test/your_type/7
    {
      "id": 7,
      "keyword": "lending club"
    }
    POST /test/your_type/8
    {
      "id": 8,
      "keyword": "ad roll"
    }
    POST /test/your_type/9
    {
      "id": 9,
      "keyword": "the honest company"
    }
    POST /test/your_type/10
    {
      "id": 10,
      "keyword": "Draft kings"
    }
    

    最后查询运行搜索:

    POST /test/your_type/_search
    {
      "query": {
        "match": {
          "keyword": "I saw the news of lending club on facebook, your story and quora"
        }
      }
    }
    

    这是结果:

    {
      "took": 6,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 4,
        "max_score": 0.009332742,
        "hits": [
          {
            "_index": "test",
            "_type": "your_type",
            "_id": "2",
            "_score": 0.009332742,
            "_source": {
              "id": 2,
              "keyword": "facebook"
            }
          },
          {
            "_index": "test",
            "_type": "your_type",
            "_id": "7",
            "_score": 0.009332742,
            "_source": {
              "id": 7,
              "keyword": "lending club"
            }
          },
          {
            "_index": "test",
            "_type": "your_type",
            "_id": "4",
            "_score": 0.009207102,
            "_source": {
              "id": 4,
              "keyword": "quora"
            }
          },
          {
            "_index": "test",
            "_type": "your_type",
            "_id": "5",
            "_score": 0.0014755741,
            "_source": {
              "id": 5,
              "keyword": "your story"
            }
          }
        ]
      }
    }
    

    那么它在幕后做了什么?

    1. 它将您的文档索引为整个关键字(它将整个字符串作为单个标记发出)。我还添加了 asciifolding 过滤器,因此它将字母标准化,即é 变为e)和小写过滤器(不区分大小写的搜索)。因此,例如 Draft kings 被索引为 draft kings
    2. 现在搜索分析器使用相同的逻辑,除了它的标记器发出单词标记并在此之上创建带状疱疹(标记组合),它将匹配您在第一步中索引的关键字。

    【讨论】:

    • 是否有人能够在 5.x 版本的 ElasticSearch 上运行它,似乎应该将映射类型从字符串更改为文本,将 index_analyzer 更改为只是分析器,但我在尝试执行搜索时遇到了 too_many_clauses 错误
    • @mac 我能够运行查询,但它们不会带回任何数据。我已经在 GitHub 上记录了这个问题:github.com/elastic/elasticsearch/issues/26989
    • 这取决于您的请求查询长度,如果它很小,您什么也得不到,如果它很长 - 弹性卡在“开销,在最后一个 [Ys] 中花费 [Xs] 收集”跨度>
    • 谢谢。我还要补充一点,可以使用 min_shingle_size 和 max_shingle_size 修改 shingle 过滤器以增加获取三字关键词
    • 大家好,我也有同样的问题,但是我不知道如何获取提取的关键字在搜索词组中的偏移量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    • 2020-11-07
    相关资源
    最近更新 更多