【问题标题】:Elastic Search Fuzzy Search root and nested fields弹性搜索模糊搜索根和嵌套字段
【发布时间】:2020-06-14 07:29:27
【问题描述】:

我是 Elastic Search 的新手,在查询时遇到了几个问题。我有一个简单的 Mongodb 数据库,其中包含城市和名胜古迹的集合。每个集合都有一个 cityName 和其他详细信息,如网站等,还有一个 places 对象数组。这是我的地图;

{
    "mappings": {
        "properties": {
            "cityName": {
                "type": "text"
            },
            "phone": {
                "type": "keyword"
            },
            "email": {
                "type": "keyword"
            },
            "website": {
                "type": "keyword"
            },
            "notes": {
                "type": "keyword"
            },
            "status": {
                "type": "keyword"
            },
            "places": {
                "type": "nested",
                "properties": {
                    "name": {
                        "type": "text"
                    },
                    "status": {
                        "type": "keyword"
                    },
                    "category": {
                        "type": "keyword"
                    },
                    "reviews": {
                        "properties": {
                            "rating": {
                                "type": "long"
                            },
                            "comment": {
                                "type": "keyword"
                            },
                            "user": {
                                "type": "nested"
                            }
                        }
                    }
                }
            }
        }
    }
}

我需要一个模糊查询,用户可以在其中搜索 cityName 和 places.name,但是当我搜索一个单词时我会得到结果,添加多个单词会返回 0 次点击。我确定我在这里遗漏了一些东西,因为我 2 天前开始学习弹性搜索。以下查询返回结果,因为我有一个包含 cityName: Islamabadplaces 数组的文档,其中包含在其 name 中具有关键字 Islamabad 的对象,在某些 places 中具有关键字 Islamabad 位于 place.name 的开头,在某些 places 对象中它可能位于中间或末尾

这就是我正在使用的:当只有一个单词时返回结果


{
  "query": {
    "bool": {
      "should": [
        {
              "fuzzy": {
                "cityName": "Islamabad"
              }

        },
        {
          "nested": {
            "path": "places",
            "query": {
              "fuzzy": {
                "places.name": "Islamabad"
              }
            }
          }
        }
      ]
    }
  }
}

当我确实有名称为Islamabad clubIslamabad Golf club 的地方时,在上述查询中添加另一个词,例如club,会返回 0 个匹配项

问题 搜索查询是从应用程序发送的,因此它是动态的,因此 cityNameplaces.nameplaces.name 的搜索词是相同的,其中并不总是包含 cityName

我到底需要什么? 我需要一个查询,我可以在其中搜索 cityName 和地点数组(仅搜索 places.name)。查询应该是 Fuzzy 类型,以便在单词 Islamabad 拼写为 Islambad 时仍然返回结果,甚至返回 IslamAbad 的结果。并且查询还应该返回多个单词的结果,我确定我在那里做错了什么。任何帮助将不胜感激。

**P.S : ** 我实际上使用 MongoDB 作为我的数据库,但迁移到 Elastic Search 只是为了改进我们的搜索功能。我在 MongoDB 上尝试了不同的方法,使用了 mongoose-fuzzy-searching npm 模块,但没有奏效,所以如果有更简单的 MongoDB 解决方案,也请分享。

谢谢。

编辑 1:

我不得不更改数据的结构(映射)。现在我有 2 个单独的索引,一个用于具有城市详细信息的城市和一个 cityId,另一个用于所有地方的索引,每个地方都有一个 cityId,如果需要,稍后将用于加入。每个地点也有一个cityName 键,所以我只会搜索地点索引,因为它包含所有详细信息(地点名称和城市名称)。

我有一个城市,其名称中包含 Welder's 一词,并且同一位置内的某些地方的名称中包含 Welder's 一词,它们的名称中包含 type:text。但是,当搜索 welder 时,以下两个查询都不会返回这些文档,而搜索 welders OR welder's 会返回这些文档。我不确定为什么welder 不会与Welder's* 匹配。在创建两个索引的过程中我没有指定任何分析器,我也没有在查询中明确定义它,任何人都可以帮助我解决这个查询,所以它的行为符合预期:

查询 1:

{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "name": {
                            "query": "welder",
                            "fuzziness": 20
                        }
                    }
                },
                 {
                    "match": {
                        "cityName": {
                            "query": "welder",
                            "fuzziness": 20
                        }
                    }
                }

            ]
        }
    }
}

查询 2:

{
    "query": {
        "match": {
            "name": {
                "query": "welder",
                "fuzziness": 20
            }
        }
    }
}

【问题讨论】:

    标签: mongodb elasticsearch mongoose fuzzy-search mongoosastic


    【解决方案1】:

    模糊查询旨在用于在一定距离内找到完整查询的近似值:

    为了找到相似的术语,模糊查询创建了一组所有可能的 指定编辑中搜索词的变体或扩展 距离。然后查询返回完全匹配每个扩展。

    如果您不能在查询中允许对单个术语进行模糊匹配,则需要使用激活了模糊性的匹配查询。

    POST <your_index>/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "cityName": {
                  "query": "Islamabad golf",
                  "fuzziness": "AUTO"
                }
              }
            },
            {
              "nested": {
                "path": "places",
                "query": {
                  "match": {
                    "places.name": {
                      "query": "Islamabad golf",
                      "fuzziness": "AUTO"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    提醒:弹性搜索中的模糊性允许每个术语最多进行 2 次更正。因此,您将永远无法将 IslamIslamabad 匹配,因为这些术语之间有 4 个更改。

    有关距离和模糊度参数的更多信息,请参阅此文档页面fuzziness parameters

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      • 2020-10-01
      • 2016-01-06
      • 2020-10-12
      • 2021-01-21
      • 2012-07-15
      • 2011-08-30
      相关资源
      最近更新 更多