elasticsearch - 弹性搜索模糊查询意外结果
问题描述
我有 2 个指数、城市和地点。Places 有一个这样的映射:
{
"mappings": {
"properties": {
"cityId": {
"type": "integer"
},
"cityName": {
"type": "text"
},
"placeName": {
"type": "text"
},
"status": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"reviews": {
"properties": {
"rating": {
"type": "long"
},
"comment": {
"type": "keyword"
},
"user": {
"type": "nested"
}
}
}
}
}
}
并且 City is index 映射如下:
{
"mappings": {
"properties": {
"state": {
"type": "keyword"
},
"postal": {
"type": "keyword"
},
"phone": {
"type": "keyword"
},
"email": {
"type": "keyword"
},
"notes": {
"type": "keyword"
},
"status": {
"type": "keyword"
},
"cityName": {
"type": "text"
},
"website": {
"type": "keyword"
},
"cityId": {
"type": "integer"
}
}
}
}
最初我们有一个文档,其中城市嵌入了地方,但我在搜索嵌套的地方数组时遇到了麻烦,所以我将结构更改为这个,我希望能够在单个查询中模糊搜索 cityName 和 placeName。我有一个城市,其名称中包含 Welder's 一词,并且同一位置内的某些地方的名称中包含 Welder's 一词,其类型为:文本。但是,当搜索welder 时,以下两个查询都不会返回这些文档,而搜索welders ORwelder's 会返回这些文档。我不确定为什么焊机与焊机*不匹配。在创建两个索引期间我没有指定任何分析器,我也没有在查询中明确定义它,任何人都可以帮助我解决这个查询,因此它的行为符合预期:
查询 1:索引 = 地点
{
"query": {
"bool": {
"should": [
{
"match": {
"placeName": {
"query": "welder",
"fuzziness": 20
}
}
},
{
"match": {
"cityName": {
"query": "welder",
"fuzziness": 20
}
}
}
]
}
}
}
查询 2:索引 = 地点
{
"query": {
"match": {
"placeName": {
"query": "welder",
"fuzziness": 20
}
}
}
}
任何人都可以发布一个查询,当传递一个单词welder时会返回他们名字中包含Welder的文档(也应该适用于这些其他术语,这只是一个例子)
编辑 1: 这是我希望上面发布的任何查询返回的示例地点文档:
{
cityId: 29,
placeName: "Welder's Garage Islamabad",
cityName: "Islamabad",
status: "verified",
category: null,
reviews: []
}
解决方案
使用您的映射和查询以及设置为“20”的模糊性,我正在取回文档。模糊性:20 将允许搜索词与welder's 之间的编辑距离为20,因此即使“w”也会与“welder's”匹配。我认为这个值在你的实际查询中是不同的。
如果要搜索焊工或焊工并返回焊工,则可以使用词干过滤器
映射:
PUT indexfuzzy
{
"mappings": {
"properties": {
"cityId": {
"type": "integer"
},
"cityName": {
"type": "text"
},
"placeName": {
"type": "text",
"analyzer": "my_analyzer"
},
"status": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"reviews": {
"properties": {
"rating": {
"type": "long"
},
"comment": {
"type": "keyword"
},
"user": {
"type": "nested"
}
}
}
}
},
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"filter": [
"lowercase",
"stem_possessive_english",
"stem_minimal_english"
]
}
},
"filter": {
"stem_possessive_english": {
"type": "stemmer",
"name": "possessive_english"
},
"stem_minimal_english": {
"type": "stemmer",
"name": "minimal_english"
}
}
}
}
}
询问 :
GET indexfuzzy/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"placeName": {
"query": "welder"--> welder,welders,welder's will work
}
}
},
{
"match": {
"cityName": {
"query": "welder"
}
}
}
]
}
}
}
结果:
[
{
"_index" : "indexfuzzy",
"_type" : "_doc",
"_id" : "Jc-yx3ABd7NBn_0GTBdp",
"_score" : 0.2876821,
"_source" : {
"cityId" : 29,
"placeName" : "Welder's Garage Islamabad",
"cityName" : "Islamabad",
"status" : "verified",
"category" : null,
"reviews" : [ ]
}
}
]
所有格英语:- 从标记中删除尾随 minimum_english:- 删除复数
GET <index_name>/_analyze
{
"text": "Welder's Garage Islamabad",
"analyzer": "my_analyzer"
}
返回
{
"tokens" : [
{
"token" : "welder", --> will be matched for welder's, welders
"start_offset" : 0,
"end_offset" : 8,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "garage",
"start_offset" : 9,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "islamabad",
"start_offset" : 16,
"end_offset" : 25,
"type" : "<ALPHANUM>",
"position" : 2
}
]
}
推荐阅读
- regex - 正则表达式查找字符串中的最后一个单词 -Javascript 风格
- azure - 将 Parquet 文件从 Azure 数据湖存储帐户复制到 Synapse 数据仓库表失败
- visual-studio-code - VSCode 调试与 Mocha 和 ESM 在 ESM“编译”文件而不是原始文件中中断
- javascript - 将 HREF 放在 DIV 中并给出滚动效果
- python-3.x - 在 Python 中遇到 lat 和 long 的类型转换
- subscription - 使用订阅时报告列显示#Error
- docker - Docker 容器未加载 wwwroot 内容 Dotnet Core 3.1
- c# - 如何写入当前进程的 StdIn?
- javascript - 在焦点上异步填充数据列表选项(获取)
- graphql - 我可以更改 Hasura Graphql 端点吗?