我正在尝试索引包含连字符但不包含空格,句点或任何其他标点符号的字符串。我不想基于连字符对单词进行拆分,而是希望将连字符作为索引文本的一部分。
例如,我的6个文本字符串将是:
我希望能够在这些字符串中搜索 包含“ play” 或 以“ magazine”开头 的 文本 。
我已经能够使用 ngram 使包含“播放”的文本正常工作。但是,连字符导致文本拆分,并且包含连字符后的单词“
magazine”中的结果。我只希望出现在以“ magazine”开头的字符串开头的单词。
根据上面的示例,当以“ magazine”开头时,只有这3个应出现:
请为我的ElasticSearch Index Sample提供帮助:
DELETE /sample
PUT /sample
{
"settings": {
"index.number_of_shards":5,
"index.number_of_replicas": 0,
"analysis": {
"filter": {
"nGram_filter": {
"type": "nGram",
"min_gram": 2,
"max_gram": 20,
"token_chars": [
"letter",
"digit"
]
},
"word_delimiter_filter": {
"type": "word_delimiter",
"preserve_original": true,
"catenate_all" : true
}
},
"analyzer": {
"ngram_index_analyzer": {
"type" : "custom",
"tokenizer": "lowercase",
"filter" : ["nGram_filter", "word_delimiter_filter"]
}
}
}
}
}
PUT /sample/1/_create
{
"name" : "magazineplayon"
}
PUT /sample/3/_create
{
"name" : "magazineofhorses"
}
PUT /sample/4/_create
{
"name" : "online-magazine"
}
PUT /sample/5/_create
{
"name" : "best-magazine"
}
PUT /sample/6/_create
{
"name" : "friend-of-magazines"
}
PUT /sample/7/_create
{
"name" : "magazineplaygames"
}
GET /sample/_search
{
"query": {
"wildcard": {
"name": "*play*"
}
}
}
GET /sample/_search
{
"query": {
"wildcard": {
"name": "magazine*"
}
}
}
更新1 我在样本后更新了所有create语句以使用TEST:
PUT /sample/test/7/_create
{
"name" : "magazinefairplay"
}
然后,我运行以下命令以仅返回其中包含“ play”一词的名称,而不执行通配符搜索。这可以正常工作,并且仅返回两条记录。
POST /sample/test/_search
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{"match": { "name.substrings": "play" }}
]
}
}
}
我运行以下命令以仅返回以“
magazine”开头的名称。我的期望是不会出现“在线杂志”,“最佳杂志”和“杂志之友”。但是,包括这三个记录在内的所有七个记录都已返回。
POST /sample/test/_search
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{"match": { "name.prefixes": "magazine" }}
]
}
}
}
有没有一种方法可以过滤掉使用连字符的前缀?
您走在正确的道路上,但是,您还需要添加另一个利用edge- ngram
令牌过滤器的分析器,以使“开头为”约束开始工作。您可以保留ngram
用于“包含”给定单词的用于检查的字段,但是您需要edge- ngram
检查用于“以”某些标记“开头”的字段。
PUT /sample
{
"settings": {
"index.number_of_shards": 5,
"index.number_of_replicas": 0,
"analysis": {
"filter": {
"nGram_filter": {
"type": "nGram",
"min_gram": 2,
"max_gram": 20,
"token_chars": [
"letter",
"digit"
]
},
"edgenGram_filter": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 20
}
},
"analyzer": {
"ngram_index_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"nGram_filter"
]
},
"edge_ngram_index_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"edgenGram_filter"
]
}
}
}
},
"mappings": {
"test": {
"properties": {
"name": {
"type": "string",
"fields": {
"prefixes": {
"type": "string",
"analyzer": "edge_ngram_index_analyzer",
"search_analyzer": "standard"
},
"substrings": {
"type": "string",
"analyzer": "ngram_index_analyzer",
"search_analyzer": "standard"
}
}
}
}
}
}
}
然后您的查询将变为(即搜索其name
字段包含play
或以开头的所有文档magazine
)
POST /sample/test/_search
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{"match": { "name.substrings": "play" }},
{"match": { "name.prefixes": "magazine" }}
]
}
}
}
注意:请勿wildcard
用于搜索子字符串,因为它会破坏群集的性能(此处和此处提供更多信息)
我正试图用在中添加自定义分隔符,但没有成功,我已经搜索了很多,并查看了下面提到的答案,但这对我没有帮助 链接1 链接2 链接3 我想在的每个项之间加上黑线,如下所示。 我在每行之间都有水平线,但不知道如何在列之间得到这些线。 chintan Soni的答案工作很好,但它只在一个场景中产生问题,当我有5个视图时,它还显示了其他3个项目的分界线,如下所示:
使用正则表达式匹配表达式 为什么这两个示例匹配如下(突出显示): c# < code>a #b #c #d 具体来说,为什么第一个字符串不匹配包含最后一个#之前的所有内容? 由于单词边界(\b)是零宽度匹配,可以在单词字符(\w)和非单词字符(\ w)之间匹配,或者在单词字符和字符串的开始或结束之间匹配,我不确定以非单词字符结束表达式会如何影响匹配。
我无法确定问题的原因,我不知道是分析器无效还是elasticsearch甚至找到了autocomplete-analyser.json文件。我该怎么解决这个?
本文向大家介绍Solr通过特殊字符分词实现自定义分词器详解,包括了Solr通过特殊字符分词实现自定义分词器详解的使用技巧和注意事项,需要的朋友参考一下 前言 我们在对英文句子分词的时候,一般采用采用的分词器是WhiteSpaceTokenizerFactory,有一次因业务要求,需要根据某一个特殊字符(以逗号分词,以竖线分词)分词。感觉这种需求可能与WhiteSpaceTokenizerFacto
我试图找到一个更好的解决方案,以防止Hibernate代理初始化时,通过MapSTRt将实体映射到响应DTO。 我一直在将我们的代码库转换为使用ModelMapper中的MapStruct。如果我想用ModelMapper完成我的要求,我可以做如下简单的事情: 自定义getter方法允许我检查是否已经从数据库中获取了字段,以避免N 1次初始化。 它看起来像: 我不能简单地覆盖普通的getter,因
问题内容: 诚然,我不太了解ES的分析部分。这是索引布局: 您可以看到我尝试对主机名字段使用自定义分析器。当我使用此查询查找名为“ WIN_1”的主机时,这种工作方式如下: 问题是它还会返回其中包含1的任何主机名。使用端点,我可以看到数字也被标记。 我想做的就是搜索WIN,并找回名称中带有WIN的所有主机。但是我还需要能够搜索WIN_1并找回确切的主机或名称中带有WIN_1的任何主机。以下是一些测