我只是从ElasticSearch开始,然后尝试基于它来实现自动完成功能。
我有一个autocomplete
带有city
type 字段的索引string
。这是存储在该索引中的文档的示例:
{
"_index":"autocomplete_1435797593949",
"_type":"listing",
"_id":"40716",
"_source":{
"city":"Rome",
"tags":[
"listings"
]
}
}
分析配置如下所示:
{
"analyzer":{
"autocomplete_term":{
"tokenizer":"autocomplete_edge",
"filter":[
"lowercase"
]
},
"autocomplete_search":{
"tokenizer":"keyword",
"filter":[
"lowercase"
]
}
},
"tokenizer":{
"autocomplete_edge":{
"type":"nGram",
"min_gram":1,
"max_gram":100
}
}
}
映射:
{
"autocomplete_1435795884170":{
"mappings":{
"listing":{
"properties":{
"city":{
"type":"string",
"analyzer":"autocomplete_term"
},
}
}
}
}
}
我将以下查询发送到ES:
{
"query":{
"multi_match":{
"query":"Rio",
"analyzer":"autocomplete_search",
"fields":[
"city"
]
}
}
}
结果,我得到以下信息:
{
"took":2,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"failed":0
},
"hits":{
"total":1,
"max_score":2.7742395,
"hits":[
{
"_index":"autocomplete_1435795884170",
"_type":"listing",
"_id":"53581",
"_score":2.7742395,
"_source":{
"city":"Rio",
"tags":[
"listings"
]
}
}
]
}
}
在大多数情况下,它是有效的。city = "Rio"
在用户必须实际键入整个单词之前,它确实找到了带有的文档("Ri"
足够了)。
这就是我的问题。我也希望它返回"Rio de Janeiro"
。要获取"Rio de Janeiro"
,我需要发送以下查询:
{
"query":{
"multi_match":{
"query":"Rio d",
"analyzer":"standard",
"fields":[
"city"
]
}
}
}
注意"<whitespace>d"
那里。
另一个相关问题是,我希望至少所有以开头的城市都"R"
将通过以下查询返回:
{
"query":{
"multi_match":{
"query":"R",
"analyzer":"standard",
"fields":[
"city"
]
}
}
}
我期望"Rome"
,等等…(这是索引中存在的文档),但是,我只能"Rio"
再次得到。我希望它的行为类似于SQL LIKE
条件,即... LIKE 'CityName%'
。
我究竟做错了什么?
我会这样做:
edge_nGram
您曾说过的需要LIKE 'CityName%'
(表示前缀匹配): "tokenizer": {
"autocomplete_edge": {
"type": "edge_nGram",
"min_gram": 1,
"max_gram": 100
}
}
autocomplete_search
为search_analyzer
。我认为拥有keyword
and 是一个不错的选择lowercase
: "mappings": {
"listing": {
"properties": {
"city": {
"type": "string",
"index_analyzer": "autocomplete_term",
"search_analyzer": "autocomplete_search"
}
}
}
}
{
"query": {
"multi_match": {
"query": "R",
"fields": [
"city"
]
}
}
}
详细的解释是这样的:将城市名称分割为ngram。例如,Rio de Janeiro
您将为以下内容编制索引:
"city": [
"r",
"ri",
"rio",
"rio ",
"rio d",
"rio de",
"rio de ",
"rio de j",
"rio de ja",
"rio de jan",
"rio de jane",
"rio de janei",
"rio de janeir",
"rio de janeiro"
]
您会注意到所有内容都是小写的。现在,您希望查询采用任何文本(是否为小写),并将其与索引中的内容匹配。因此,R
应该与上面的列表匹配。
为此,您希望输入文本小写并与用户设置的文本保持一致,这意味着不应对其进行分析。你为什么要这个?因为您已经用ngram分割了城市名称,并且不想为输入文本使用相同的名称。如果用户输入“
RI”,Elasticsearch将小写ri
--并将其与索引中的内容完全匹配。
可能更快的替代方法multi_match
是使用term
,但这要求您的应用程序/网站将文本小写。这样做的原因是term
根本不分析输入文本。
{
"query": {
"filtered": {
"filter": {
"term": {
"city": {
"value": "ri"
}
}
}
}
}
}
问题内容: 我在Elasticsearch中有一个带有value的字段。当我要使用查询字符串“ cgn:4189”进行搜索时,没有结果。我尝试像“ cgn:4189”那样逃脱冒号,但是我有语法错误。我不知道该怎么做。 结果: 和 结果: 你能帮我吗? 问题答案: 尝试以下查询,看看它是否适合您: 这是一些我用来测试的Sense代码: http://sense.qbox.io/gist/1c9096
问题内容: 弹性搜寻1.6 我想索引包含连字符的文本,例如U-12,U-17,WU-12,T恤…,并能够使用“简单查询字符串”查询来搜索它们。 数据样本(简体): 所以我去了这个映射: 使用以下查询进行搜索: 什么有效: “ U-12”,“ U ”,“ t ”,“ ts *” 什么不起作用: “ U-”,“ u-1 ”,“ t-”,“ t-sh ”,… 看来char过滤器未在搜索字符串上执行?我该
问题内容: 我已经使用此批量请求设法用4个文档填充了索引: 开机自检 现在如何在所有可用 标题* 上使用 通配符 进行 搜索 ? *** 类似于 但提供一个或多个通配符的东西。例如,搜索“ ”并解析来自elasticsearch的响应以最终返回如下内容: 谢谢! 问题答案: Elasticsearch在常规匹配查询中提供正则表达式支持 给你这个 要更新到您的问题URI搜索,我不确定是否可行,如果使
是否有人成功地将search\u after与spring data elasticsearch一起使用? 我已经将_uid添加到我的排序中,@Controller正确地将其放入我的Pagable中。我打开了慢速查询日志并验证了如果我手动运行@Repository生成的查询,我会得到响应: 我将以下内容添加到我的pojo(由@Repository返回的类): 排序总是返回为null。尝试了两种不同
我现在从Elasticsearch开始。我为一些EDIFACT消息(一种史前数据格式;-)编制了索引,内容如下: 当我搜索短语UNH 66304 CODECO: D:95B时,它应该只返回一次命中,但它似乎返回了包含任何这些单词的所有文件(并且UNH在每个文档中)。我的查询是: 我尝试添加“and”操作符,如下所示: 但是没有返回结果。我在这里读到了建议:搜索需要使用双引号的确切短语。我试过“查询
Elasticsearch 作为一个 Java 应用,本身的部署已经非常简单了。不过作为生产环境,还是有必要采用一些更标准化的方式进行集群的管理。Elasticsearch 官方提供并推荐使用 Puppet 方式部署和管理。其 Puppet 模块源码地址见: https://github.com/elastic/puppet-elasticsearch 安装方法 和其他标准 Puppet Modu