首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于完成提示器的标记字符串

用于完成提示器的标记字符串
EN

Stack Overflow用户
提问于 2018-11-01 08:05:20
回答 2查看 1.8K关注 0票数 3

想要构建一个电子商务网站的自动完成功能,使用完成提示器。

这是我的索引:

代码语言:javascript
复制
PUT myIndex
{
    "mappings": {
        "_doc" : {
            "properties" : {
                "suggest" : {
                    "type" : "completion"
                },
                "title" : {
                    "type": "keyword"
                }, 
                "category" : { 
                    "type": "keyword"
                },
                "description" : { 
                    "type": "keyword"
                }
            }
        }
    }
}

现在,在上传广告时,我希望标题字段用于自动完成,所以我是这样上传文档的:

代码语言:javascript
复制
POST dummy/_doc
{
  "title": "Blue asics running shoes",
  "category": "sports",
  "description": "Nice blue running shoes, size 44 eu",
  "suggest": {
    "input": "Blue Asics running shoes" // <-- use title
  }
}

问题是,这样,弹性搜索只能从一开始就匹配字符串.即"Blu“会找到结果,但是"Asic”、"Run“或"Sho”不会返回任何东西.

因此,我需要做的是像这样标记我的输入:

代码语言:javascript
复制
POST dummy/_doc
{
  "title": "Blue asics running shoes",
  "category": "sports",
  "description": "Nice blue running shoes, size 44 eu",
  "suggest": {
    "input": ["Blue", "Asics", "running", "shoes"] // <-- tokenized title
  }
}

这会很好..。但我该怎么标记我的场呢?我知道我可以在c#中拆分字符串,但是我是否可以在Elasticsearch/Nest中这样做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-01 23:04:36

完形暗示器是为快速搜索即你类型的前缀查询而设计的,使用的是simple分析器,而不是standard分析器,后者是text数据类型的默认值。

如果需要对标题中的任何标记进行部分前缀匹配,而不仅仅是从标题开始,则可以考虑采用以下方法之一:

  1. 分析API与分析器一起使用,该分析器会将标题标记为要进行部分前缀匹配的标记/术语,并将该集合作为input索引到completion字段。标准分析器可能是一个好的开始。 请记住,完成提示器的数据结构在使用时保存在内存中,因此跨文档的高术语基数将增加该数据结构的内存需求。还要考虑匹配项的“评分”很简单,因为它是由应用于每个输入的权重控制的。

  1. 不要在这里使用完成提示器,而是将title字段设置为带有多场text数据类型,其中包括应该分析title的不同方式(或者不使用keyword子字段)。 花一些时间在analyzer上构建一个分析器,允许在标题中的任何地方使用部分前缀。首先,像标准令牌器、小写令牌过滤器、Edgengram令牌过滤器和可能停止令牌过滤器这样的东西可以让您运行。还要注意,除了Edgengram令牌过滤器之外,您还需要一个与索引分析器类似的搜索分析器,因为搜索输入中的标记不需要进行命名。
票数 2
EN

Stack Overflow用户

发布于 2018-11-02 00:39:22

基于Russ上面的答案(选项2)、这个弹性搜索指南本文件,我得到了以下解决方案:

代码语言:javascript
复制
PUT my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "edge_ngram_token_filter": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10
        },
        "additional_stop_words": {
          "type":       "stop",
          "stopwords":  ["your"]
        },
        "english_stemmer": {
          "type":       "stemmer",
          "language":   "english"
        },
        "english_possessive_stemmer": {
          "type":       "stemmer",
          "language":   "possessive_english"
        }
      },
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": [
            "C# => csharp",
            "c# => csharp"
          ]
        }
       },
       "analyzer": {
        "result_suggester_analyzer": { 
          "type": "custom",
          "tokenizer": "standard",
          "char_filter":  [ "html_strip", "my_char_filter" ],
          "filter": [
            "english_possessive_stemmer",
            "lowercase",
            "asciifolding",
            "stop",
            "additional_stop_words",
            "english_stemmer",
            "edge_ngram_token_filter",
            "unique"
          ]
        }
      }
    }
  }
}

查询以测试此解决方案:

代码语言:javascript
复制
POST my_index/_analyze
{
  "analyzer": "result_suggester_analyzer",
  "text": "C# &amp; SQL are great languages. K2 is the mountaineer's mountain. Your house-décor is à la Mode"
}

我会得到这些令牌(NGrams):

代码语言:javascript
复制
cs, csh, csha, cshar, csharp, sq, sql, gr, gre, grea, great, la, lan, lang,
langu, langua, languag, k2, mo, mou, moun, mount, mounta, mountai, mountain, 
ho, hou, hous, hous, de, dec, deco, decor, mod, mode

这里要注意的是:

  1. 我使用的是stop过滤器,它是默认的英语语言过滤器,并阻塞are, is, the -但不是your
  2. 我已经定义了additional_stop_words,它停止了your
  3. 我使用的是内置于english & possessive_english词干分析器,这将标记词干:这就是为什么我们有语言标记,而不是语言或语言.还请注意,我们有山,但没有登山。
  4. 我已经定义了mapped_words_char_filter,它将C#转换为csharp,如果没有这个c#将不是一个有效的令牌.(此设置不会将F#标记化)
  5. 我使用的是内置的html_stripchar_filter,它将&amp;转换为&,因为min_gram =2被忽略了。
  6. 我们正在使用构建它的asciifolding令牌过滤器,这就是为什么décor被标记为装饰。

这是上面的嵌套代码:

代码语言:javascript
复制
var createIndexResponse = ElasticClient.CreateIndex(IndexName, c => c
    .Settings(st => st
        .Analysis(an => an
            .Analyzers(anz => anz
                .Custom("result_suggester_analyzer", cc => cc
                    .Tokenizer("standard")
                    .CharFilters("html_strip", "mapped_words_char_filter")
                    .Filters(new string[] { "english_possessive_stemmer", "lowercase", "asciifolding", "stop", "english_stemmer", "edge_ngram_token_filter", "unique" })
                )
            )
            .CharFilters(cf => cf
                .Mapping("mapped_words_char_filter", md => md
                    .Mappings(
                        "C# => csharp",
                        "c# => csharp"
                    )
                )
            )
            .TokenFilters(tfd => tfd
                .EdgeNGram("edge_ngram_token_filter", engd => engd
                    .MinGram(2)
                    .MaxGram(10)
                )
                .Stop("additional_stop_word", sfd => sfd.StopWords(new string[] { "your" }))
                .Stemmer("english_stemmer", esd => esd.Language("english"))
                .Stemmer("english_possessive_stemmer", epsd => epsd.Language("possessive_english"))
            )
        )
    )
    .Mappings(m => m.Map<AdDocument>(d => d.AutoMap())));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53097275

复制
相关文章

相似问题

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