elasticsearch,Java,Search,elasticsearch" /> elasticsearch,Java,Search,elasticsearch" />

Java 使用elasticsearch对文本进行分类

Java 使用elasticsearch对文本进行分类,java,search,elasticsearch,Java,Search,elasticsearch,我目前正在从事一个项目,该项目涉及从文本中识别不同的“关键字” 例如,假设以下输入文本: “这是布宜诺斯艾利斯关于肉类的一些文字的一个例子” 进一步假设我的elasticsearch实例存储了以下文档: 城市:[巴塞罗那、布宜诺斯艾利斯、洛杉矶,…] 及 类别:[金融、政治,…] 我需要一种从输入文本中识别相应城市和类别的方法 我的第一个方法是使用“or”操作符进行搜索查询,看看哪一个排名最高。之后,我还会将匹配的文档与文本重新匹配,以确保这些文本确实存在(换句话说,确保“los angeles

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

例如,假设以下输入文本:

“这是布宜诺斯艾利斯关于肉类的一些文字的一个例子”

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

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

类别:[金融、政治,…]

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

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

我想知道这是否是使用Elasticsearch执行此类操作的最佳实践方式。

基本上是基于顶部的,因此您可以使用任何您想要的Apaches查询:

+

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

要将“关键字”识别为以前的索引值并避免“洛杉矶”这样的情况,最好的办法是在未分析的字段中使用术语facet查询。 注意内存开销,并查看更多示例。
干杯

我建议如下:

  • 使用查询来确定术语
    洛杉矶
    洛杉矶
    是否存在,以及它们是否以相同的顺序和位置存在
  • 将每个查询包装在一个表中,以便您可以确定哪些查询匹配
例如,创建此文档:

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"
}
'
然后运行此查询,查找
布宜诺斯艾利斯
洛杉矶

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\u filters
元素,它指示匹配的过滤器。

看起来这也可能是一个很好的匹配结果

您可以将查询作为单独索引上的文档进行索引,然后对文档进行过滤,以了解它们与哪些查询匹配

您需要创建一个索引(使用),我们称之为test,例如:

curl -XPUT localhost:9200/test
然后注册我们的“布宜诺斯艾利斯”查询,给它一个名字。匹配短语查询似乎是一个不错的选择,正如DrTech在他的回答中所建议的那样

curl -XPUT localhost:9200/_percolator/test/buenosaires -d '{
    "query" : {
        "match_phrase" : {
            "text" : "Buenos Aires"
        }
    }
}'
然后percolate,这意味着我们发送一个文档,并在我们之前索引的查询中返回它匹配的查询:

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可能更适合


希望这有帮助!

嗨,谢谢你的回答。我知道ElasticSearch,我已经使用过好几次了。我正在寻找一个最佳实践来涵盖前面解释的示例。只有当你已经在一个单独的字段中有类别时,这才有效。如果你有一个包含城市名称的大文本,你确实需要分析它。我猜你的方法不适合这个问题。这似乎正是我想要的!我会尽快尝试!太多了!你能接受你在这里得到的最好答案吗?