elasticsearch:如何索引只有停用词的术语?

时间:2013-02-01 06:08:38

标签: indexing elasticsearch stop-words

我在后台使用elasticsearch构建自己的小搜索有很大的成功。但是有一件事我在文档中找不到。

我正在索引音乐家和乐队的名字。有一个乐队名为“The The”,由于停止词汇列表,这个乐队从未被编入索引。

我知道我可以完全忽略停用词列表,但这不是我想要的,因为搜索其他乐队的结果如“谁”会爆炸。

那么,是否可以在索引中保存“The The”但是根本不能禁用停用词?

1 个答案:

答案 0 :(得分:5)

您可以使用synonym filterThe The转换为单个标记,例如thethe,停用词过滤器不会将其删除。

首先,配置分析器:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "syn" : {
               "synonyms" : [
                  "the the => thethe"
               ],
               "type" : "synonym"
            }
         },
         "analyzer" : {
            "syn" : {
               "filter" : [
                  "lowercase",
                  "syn",
                  "stop"
               ],
               "type" : "custom",
               "tokenizer" : "standard"
            }
         }
      }
   }
}
'

然后使用字符串"The The The Who"对其进行测试。

curl -XGET 'http://127.0.0.1:9200/test/_analyze?pretty=1&text=The+The+The+Who&analyzer=syn' 

{
   "tokens" : [
      {
         "end_offset" : 7,
         "position" : 1,
         "start_offset" : 0,
         "type" : "SYNONYM",
         "token" : "thethe"
      },
      {
         "end_offset" : 15,
         "position" : 3,
         "start_offset" : 12,
         "type" : "<ALPHANUM>",
         "token" : "who"
      }
   ]
}

"The The"已标记为"the the""The Who"已标记为"who",因为前一个"the"已被停用词过滤器删除。

停止或不停止

这让我们回到是否应该包含停用词?你说:

I know I can ignore the stop words list completely 
but this is not what I want since the results searching 
for other bands like "the who" would explode.

你是什么意思?怎么爆炸?指数大小?性能

最初引入了停用词是为了通过删除可能对查询的相关性几乎没有影响的常用词来提高搜索引擎的性能。但是,从那以后我们走了很长一段路。我们的服务器能够比80年代的服务器更多。

索引停用词不会对索引大小产生巨大影响。例如,索引单词the意味着向索引添加单个术语。您已经拥有数千个术语 - 对停用词编制索引也不会对大小或性能产生太大影响。

实际上,更大的问题是the非常常见,因此对相关性的影响很小,因此搜索"The The concert Madrid"会优先Madrid而不是其他条款。 这可以通过使用shingle过滤器来减轻,这会导致这些令牌:

['the the','the concert','concert madrid']

虽然the可能很常见,但the the却不常见,因此排名会更高。

您不会自己查询带状疱疹的字段,但是您可以将查询与标准分析器(没有停用词)标记的字段和对带状疱疹字段的查询相结合。

我们可以使用多字段以两种不同的方式分析text字段:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "mappings" : {
      "test" : {
         "properties" : {
            "text" : {
               "fields" : {
                  "shingle" : {
                     "type" : "string",
                     "analyzer" : "shingle"
                  },
                  "text" : {
                     "type" : "string",
                     "analyzer" : "no_stop"
                  }
               },
               "type" : "multi_field"
            }
         }
      }
   },
   "settings" : {
      "analysis" : {
         "analyzer" : {
            "no_stop" : {
               "stopwords" : "",
               "type" : "standard"
            },
            "shingle" : {
               "filter" : [
                  "standard",
                  "lowercase",
                  "shingle"
               ],
               "type" : "custom",
               "tokenizer" : "standard"
            }
         }
      }
   }
}
'

然后使用multi_match查询来查询该字段的两个版本,从而为带状疱疹版本提供更多“提升”/相关性。在此示例中,text.shingle^2表示我们希望将该字段提升2:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "multi_match" : {
         "fields" : [
            "text",
            "text.shingle^2"
         ],
         "query" : "the the concert madrid"
      }
   }
}
'