【问题标题】:categorize text with elasticsearch使用 elasticsearch 对文本进行分类
【发布时间】:2013-02-10 08:33:03
【问题描述】:

我目前正在从事一个项目,该项目涉及从文本中识别不同的“关键字”。

作为一个例子,让我们假设以下输入文本:

“这是一些来自布宜诺斯艾利斯的关于肉类的文字示例”。

进一步假设我的 elasticsearch 实例存储了以下文档:

城市:[巴塞罗那、布宜诺斯艾利斯、洛杉矶……]

类别:[金融、政治、..]

我需要一种方法来从输入文本中识别相应的城市和类别。

我的第一种方法是使用“或”运算符进行搜索查询,看看哪个排名最高。之后,我还将匹配的文档与文本重新匹配,以确保这些文本确实存在(换句话说,确保“los angeles”匹配,因为“los angeles”这个词在文本中并且只有“los”或“天使”。

我想知道这是否是使用 Elasticsearch 做这类事情的最佳实践方式。

【问题讨论】:

  • 您能接受您在这里得到的最佳答案吗?

标签: java search elasticsearch


【解决方案1】:

看起来这也很适合Percolator

您可以将您的查询作为单独索引上的文档进行索引,然后渗透您的文档以了解它们匹配哪些查询。看看percolate API

您需要创建一个索引(使用create index API),我们称之为测试,例如:

curl -XPUT localhost:9200/test

然后注册我们的“布宜诺斯艾利斯”查询并为其命名。正如 DrTech 在他的回答中建议的那样,匹配短语查询似乎是一个不错的选择。

curl -XPUT localhost:9200/_percolator/test/buenosaires -d '{
    "query" : {
        "match_phrase" : {
            "text" : "Buenos Aires"
        }
    }
}'

然后渗透,这意味着我们发送一个文档,然后我们返回它与我们之前索引的查询中匹配的查询:

curl -XGET localhost:9200/test/type1/_percolate -d '{
    "doc" : {
        "city" : "This is an example of some text written from Buenos Aires about Meat"
    }
}'

在这种情况下,您应该返回以下 json,其中 buenosaires 是我们在索引查询时为查询指定的名称:

{"ok":true, "matches":["buenosaires"]}

DrTech 的回答非常好。我认为主要区别在于您的文字实际在哪里。如果它已经在 elasticsearch 中被索引,那么最好的策略是进行命名查询以在单个请求中获取您的文档匹配的内容。

另一方面,如果您要为数据编制索引,并且需要在实际编制索引之前丰富您的文档,那么 percolator 可能更适合。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    我建议如下:

    • 使用match_phrase 查询来确定术语losangeles 存在并且以相同的顺序和位置存在
    • 将每个查询包装在 named filter 中,以便您识别匹配的查询。

    例如,创建这个文档:

    curl -XPOST 'http://127.0.0.1:9200/test/test?pretty=1'  -d '
    {
       "text" : "This is an example of some text written from Buenos Aires about Meat"
    }
    '
    

    然后运行此查询以查找 Buenos AiresLos Angeles

    curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
    {
       "query" : {
          "constant_score" : {
             "filter" : {
                "or" : [
                   {
                      "fquery" : {
                         "_name" : "buenos_aires",
                         "query" : {
                            "match_phrase" : {
                               "text" : "Buenos Aires"
                            }
                         }
                      }
                   },
                   {
                      "fquery" : {
                         "_name" : "los_angeles",
                         "query" : {
                            "match_phrase" : {
                               "text" : "Los Angeles"
                            }
                         }
                      }
                   }
                ]
             }
          }
       }
    }
    '
    
    # {
    #    "hits" : {
    #       "hits" : [
    #          {
    #             "_source" : {
    #                "text" : "This is an example of some text written from Buenos Aires about Meat"
    #             },
    #             "_score" : 1,
    #             "_index" : "test",
    #             "_id" : "JIwnN_FVTv-0i5YGrlHLeg",
    #             "_type" : "test",
    #             "matched_filters" : [
    #                "buenos_aires"
    #             ]
    #          }
    #       ],
    #       "max_score" : 1,
    #       "total" : 1
    #    },
    #    "timed_out" : false,
    #    "_shards" : {
    #       "failed" : 0,
    #       "successful" : 5,
    #       "total" : 5
    #    },
    #    "took" : 58
    # }
    

    注意结果中的matched_filters 元素,指示匹配的过滤器。

    【讨论】:

    • 这似乎正是我想要的!我会尽快试一试!非常感谢!
    【解决方案3】:

    将“关键字”标识为以前的索引值并避免“los”“angeles”等情况的最佳选择是使用术语 facet 查询未分析的字段。 请注意内存成本并查看here 以获取更多示例。 干杯

    【讨论】:

    • 这只有在您已经在单独的字段中有类别时才有效。如果您有一个包含城市名称的大文本,则需要对其进行分析。我猜你的方法不适合这个问题。
    【解决方案4】:

    Elastic search 基本上是基于Apache Lucene 之上的,因此您可以使用任何您想要的 Apaches 查询:

    query command + query syntax

    在您的情况下,我建议您查看“字段”查询:

    http://www.elasticsearch.org/guide/reference/query-dsl/field-query.html

    【讨论】:

    • 您好,感谢您的回答。我知道 ElasticSearch,我已经用过几次了。我正在寻找一个最佳实践来涵盖前面解释的示例。
    猜你喜欢
    • 2015-03-16
    • 2018-11-07
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 2017-08-08
    • 2016-09-25
    • 2020-09-28
    相关资源
    最近更新 更多