弹性搜索&耐嚼:根据项目内容制作结果uniq

时间:2016-02-02 14:06:23

标签: elasticsearch chewy-gem

很抱歉标题不清晰,但我不确定如何用简单的句子表达我的问题。

解释:我目前使用的应用程序有多种类型的对象,可以链接到用户添加的标记。目前,每个标记都是数据库中的不同条目。

比方说让我说:   - 对象1标记为:tag1,tag2   - 对象2标记为:tag2,tag3   - 对象3标记为:tag1,tag3,tag4

标签的表格如下:

id | value | tagged object
 1 | tag1  | 1
 2 | tag2  | 1
 3 | tag2  | 2
 4 | tag3  | 2
 5 | tag1  | 3
 6 | tag3  | 3
 7 | tag4  | 3

标签的值也在弹性搜索中索引(使用耐嚼的宝石),因此应用程序会在标签上提供一些自动完成功能。

主要问题是,当搜索'ta'时,弹性搜索将返回列表:tag1,tag2,tag2,tag3,tag1,tag3,tag4,这会导致一些麻烦。 让我们假设我们有100个标记为“tag1”的对象,而101st标记为“tag2”。如果我搜索“ta”,则不会返回“tag2”(因此不会被建议)。

我想要的是搜索查询返回:tag1,tag2,tag3,tag4(我真的不关心所说的顺序),所以基本上根据索引标记的值统一结果而不是整个对象。 我希望我的问题足够清楚:)

提前致谢:)

因为它可能会有所帮助,这里是用于声明索引和索引元素的代码(是的,索引有两个字段,但是用单个字段很难解释;)

class SuggestionsIndex < Chewy::Index
  settings analysis: {
    filter: {
      ngram: {
        type: 'nGram',
        min_gram: 1,
        max_gram: 50,
        token_chars: [ 'letter', 'digit']
      }
    },
    tokenizer: {
      ngram_tokenizer: {
        type: 'nGram',
        min_gram: 1,
        max_gram: 50,
        token_chars: [ 'letter', 'digit', 'punctuation', 'symbol']
      }
    },
    analyzer: {
      # ngram indexing allows searching for a substring in words
      ngram: {
        tokenizer: 'ngram_tokenizer',
        filter: ['lowercase', 'asciifolding']
      },
      # when searching, we search for the lowercase words, not the ngram
      lowerascii_search: {
        tokenizer: 'whitespace',
        filter: ['lowercase', 'asciifolding']
      }
    }
  }

  define_type Tag do
    field :key,
      index_analyzer: 'ngram',
      search_analyzer: 'lowerascii_search'
    field :value,
      index_analyzer: 'ngram',
      search_analyzer: 'lowerascii_search'
    field :project_id, type: 'integer'
  end
end

1 个答案:

答案 0 :(得分:0)

如果您希望弹性搜索确切的值,则要么创建字段not_analyzed,要么在类型或索引级别使用keyword标记生成器(而不是ngram)。