弹性搜索模糊搜索根字段和嵌套字段

时间:2020-03-02 01:28:28

标签: mongodb elasticsearch mongoose fuzzy-search mongoosastic

我是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个匹配。我确定我在这里遗漏了一些东西,因为我两天前开始学习弹性搜索。以下查询返回结果,因为我有一个文档,该文档的cityName: Islamabadplaces数组在其name中的某些对象{{1}中具有关键字 Islamabad }}关键字伊斯兰堡位于places的开头,在某些place.name对象中,关键字可能位于中间或结尾

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

places

当我实际上确实有名称为 { "query": { "bool": { "should": [ { "fuzzy": { "cityName": "Islamabad" } }, { "nested": { "path": "places", "query": { "fuzzy": { "places.name": "Islamabad" } } } } ] } } } club的地方时,在上面的查询中添加另一个词,例如Islamabad club会返回0次匹配。

问题 搜索查询是从应用发送的,因此它是动态的,因此Islamabad Golf clubcityName的搜索词是相同的,并且places.name并不总是具有{{1} }。

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

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

谢谢。

编辑1:

我不得不更改数据的结构(映射)。现在,我有2个单独的索引,一个索引包含具有城市详细信息和Abad的城市,而另一个索引则包含所有地点的索引,每个地点都有一个mongoose-fuzzy-searching,以后将在需要时用于连接。每个地点还具有一个cityId键,因此我将仅搜索地点索引,因为它具有所有详细信息(地点名称和城市名称)。

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

查询1:

welder

查询2:

Welder's*

1 个答案:

答案 0 :(得分:0)

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

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

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

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"
                }
              }
            }
          }
        }
      ]
    }
  }
}

提醒:elasticsearch中的模糊性允许每学期最多进行2次更正。因此,您将永远无法将IslamIslamabad匹配,因为这两个词之间有4个变化。

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