首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用ElasticSearch搜索单词的一部分

如何使用ElasticSearch搜索单词的一部分
EN

Stack Overflow用户
提问于 2011-06-24 19:24:52
回答 11查看 132.8K关注 0票数 148

我最近开始使用ElasticSearch,但我似乎不能让它搜索单词的一部分。

示例:我在ElasticSearch中索引了couchdb中的三个文档:

代码语言:javascript
复制
{
  "_id" : "1",
  "name" : "John Doeman",
  "function" : "Janitor"
}
{
  "_id" : "2",
  "name" : "Jane Doewoman",
  "function" : "Teacher"
}
{
  "_id" : "3",
  "name" : "Jimmy Jackal",
  "function" : "Student"
} 

所以现在,我要搜索所有包含"Doe“的文档

代码语言:javascript
复制
curl http://localhost:9200/my_idx/my_type/_search?q=Doe

不会返回任何命中结果。但如果我搜索

代码语言:javascript
复制
curl http://localhost:9200/my_idx/my_type/_search?q=Doeman

它确实返回了一个文档(John Doeman)。

我已经尝试将不同的分析器和过滤器设置为我的索引的属性。我还尝试使用完整的查询(例如:

代码语言:javascript
复制
{
  "query": {
    "term": {
      "name": "Doe"
    }
  }
}

),但似乎什么都不起作用。

当我搜索“无名氏”时,如何让ElasticSearch同时找到约翰·多曼和简·多伊曼?

更新

我尝试使用nGram标记器和过滤器,就像伊戈尔提议的那样,如下所示:

代码语言:javascript
复制
{
  "index": {
    "index": "my_idx",
    "type": "my_type",
    "bulk_size": "100",
    "bulk_timeout": "10ms",
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "tokenizer": "my_ngram_tokenizer",
          "filter": [
            "my_ngram_filter"
          ]
        }
      },
      "filter": {
        "my_ngram_filter": {
          "type": "nGram",
          "min_gram": 1,
          "max_gram": 1
        }
      },
      "tokenizer": {
        "my_ngram_tokenizer": {
          "type": "nGram",
          "min_gram": 1,
          "max_gram": 1
        }
      }
    }
  }
}

我现在遇到的问题是,每个查询都返回所有文档。有什么建议吗?关于使用nGram的ElasticSearch文档不是很好...

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2011-09-20 17:47:54

我也在使用nGram。我使用标准的标记器和nGram作为过滤器。下面是我的设置:

代码语言:javascript
复制
{
  "index": {
    "index": "my_idx",
    "type": "my_type",
    "analysis": {
      "index_analyzer": {
        "my_index_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "mynGram"
          ]
        }
      },
      "search_analyzer": {
        "my_search_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "standard",
            "lowercase",
            "mynGram"
          ]
        }
      },
      "filter": {
        "mynGram": {
          "type": "nGram",
          "min_gram": 2,
          "max_gram": 50
        }
      }
    }
  }
}

让我们找出最多50个字母的单词部分。根据需要调整max_gram。在德语中,可以变得非常大,所以我将其设置为一个很高的值。

票数 90
EN

Stack Overflow用户

发布于 2011-06-25 01:23:41

在大型索引上,使用前导和尾随通配符进行搜索将非常慢。如果希望能够按单词前缀进行搜索,请删除前导通配符。如果你真的需要在单词中间找到一个子串,你最好使用ngram标记器。

票数 68
EN

Stack Overflow用户

发布于 2017-04-07 21:00:01

我认为没有必要更改任何映射。尝试使用query_string,它是完美的。所有场景都将使用默认标准分析器:

我们有数据:

代码语言:javascript
复制
{"_id" : "1","name" : "John Doeman","function" : "Janitor"}
{"_id" : "2","name" : "Jane Doewoman","function" : "Teacher"}

场景1:

代码语言:javascript
复制
{"query": {
    "query_string" : {"default_field" : "name", "query" : "*Doe*"}
} }

响应:

代码语言:javascript
复制
{"_id" : "1","name" : "John Doeman","function" : "Janitor"}
{"_id" : "2","name" : "Jane Doewoman","function" : "Teacher"}

场景2:

代码语言:javascript
复制
{"query": {
    "query_string" : {"default_field" : "name", "query" : "*Jan*"}
} }

响应:

代码语言:javascript
复制
{"_id" : "1","name" : "John Doeman","function" : "Janitor"}

场景3:

代码语言:javascript
复制
{"query": {
    "query_string" : {"default_field" : "name", "query" : "*oh* *oe*"}
} }

响应:

代码语言:javascript
复制
{"_id" : "1","name" : "John Doeman","function" : "Janitor"}
{"_id" : "2","name" : "Jane Doewoman","function" : "Teacher"}

编辑-与spring data elastic search https://stackoverflow.com/a/43579948/2357869实现相同

另一个解释query_string比其他https://stackoverflow.com/a/43321606/2357869更好的原因

票数 67
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6467067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档