我有如下映射的elasticsearch类型,
mappings": {
"jardata": {
"properties": {
"groupID": {
"index": "not_analyzed",
"type": "string"
},
"artifactID": {
"index": "not_analyzed",
"type": "string"
},
"directory": {
"type": "string"
},
"jarFileName": {
"index": "not_analyzed",
"type": "string"
},
"version": {
"index": "not_analyzed",
"type": "string"
}
}
}
}
我使用的是分析后的目录索引,因为我只想给出最后一个文件夹并获取结果,但是当我要搜索特定目录时,我需要给出整个路径,因为在两个路径中可以有相同的文件夹。这里的问题是,因为将对它进行分析,然后将所有数据代替我想要的特定数据。
这里的问题是我想像已分析的和未分析的那样进行操作。有办法吗?
假设您已将以下文档编入索引:
{
"directory": "/home/docs/public"
}
在您的情况下,标准分析器还不够,因为它会在建立索引时创建以下术语:
[home, docs, public]
请注意,它会丢失[/home/docs/public]
标记-像“ /”等字符在此处充当分隔符。
一种解决方案是将NGram标记生成器与列表中的punctuation
字符类一起使用token_chars
。Elasticsearch会将“ /”视为字母或数字。这将允许使用以下标记进行搜索:
[/hom, /home, ..., /home/docs/publi, /home/docs/public, ..., /docs/public, etc...]
索引映射:
{
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 4,
"max_gram": 18,
"token_chars": [
"letter",
"digit",
"punctuation"
]
}
}
}
},
"mappings": {
"jardata": {
"properties": {
"directory": {
"type": "string",
"analyzer": "ngram_analyzer"
}
}
}
}
}
现在这两个搜索查询:
{
"query": {
"bool" : {
"must" : {
"term" : {
"directory": "/docs/private"
}
}
}
}
}
和
{
"query": {
"bool" : {
"must" : {
"term" : {
"directory": "/home/docs/private"
}
}
}
}
}
将给出结果中的索引文件。
您必须考虑的一件事是在"max_gram"
设置中指定的令牌的最大长度。如果是目录路径,则可能需要更长的时间。
另一种解决方案是使用Whitespace tokenizer,它将短语仅在空白上分解为术语,并使用具有以下映射的NGram过滤器:
{
"settings": {
"analysis": {
"filter": {
"ngram_filter": {
"type": "ngram",
"min_gram": 4,
"max_gram": 20
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "whitespace",
"filter": [
"lowercase",
"ngram_filter"
]
}
}
}
},
"mappings": {
"jardata": {
"properties": {
"directory": {
"type": "string",
"analyzer": "my_analyzer"
}
}
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句