我目前正在开展一个项目,该项目涉及从文本中识别不同的“关键字”。
作为示例,我们假设以下输入文本:
“这是布宜诺斯艾利斯关于肉类的一些文字的例子”。
进一步假设我的elasticsearch实例存储了以下文档:
城市:[巴塞罗那,布宜诺斯艾利斯,洛杉矶......]
和
分类:[金融,政治,......]
我需要一种方法来从输入文本中识别相应的城市和类别。
我的第一种方法是使用“或”运算符进行搜索查询,并查看哪一个具有最高排名。之后,我还将匹配的文件与文本重新匹配,以确保这些文本确实存在(换句话说,确保“洛杉矶”匹配,因为“洛杉矶”一词在文本中,只有“洛杉矶”或“洛杉矶)。
我想知道它是否是使用Elasticsearch进行此类事情的最佳实践方式。
答案 0 :(得分:5)
我建议如下:
match_phrase
次查询来确定术语los
和angeles
是否存在且存在于相同的顺序和位置例如,创建此文档:
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 Aires
或Los 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
元素,指示哪个过滤器匹配。
答案 1 :(得分:2)
看起来这可能也适合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中编入索引,那么最好的策略是使命名查询在单个请求中找回文档匹配的内容。
另一方面,如果您要对数据进行索引,并且需要在实际索引之前丰富文档,那么过滤器可能更适合。
希望这有帮助!
答案 2 :(得分:0)
将“关键字”标识为先前索引值并避免“los”“angeles”等情况的最佳选择是使用术语构面查询作为非分析字段。 请注意内存成本,并查看here以获取更多示例。 干杯
答案 3 :(得分:-2)
Elastic search基本上基于Apache Lucene的顶部,因此您可以使用任何您想要的Apaches查询:
在你的情况下,我建议你查看“Fields”查询:
http://www.elasticsearch.org/guide/reference/query-dsl/field-query.html