在ElasticSearch中搜索时删除连字符

在ElasticSearch中搜索时删除连字符,
Warning: implode(): Invalid arguments passed in /data/phpspider/zhask/webroot/tpl/detail.html on line 45
,,我想使用ElasticSearch和SpringData创建图书搜索 我用不带连字符的ISBN/EAN为我的书编制索引,并将其保存在数据库中。我用ElasticSearch索引了这些数据 索引数据:1113333444444 如果我正在搜索带连字符的ISBN/EAN:111-3333-4444 没有结果。如果我搜索时没有连字符,我的书将按预期找到 我的设置如下: { "analysis": { "filter": { "c

我想使用ElasticSearch和SpringData创建图书搜索

我用不带连字符的ISBN/EAN为我的书编制索引,并将其保存在数据库中。我用ElasticSearch索引了这些数据

索引数据:1113333444444 如果我正在搜索带连字符的ISBN/EAN:111-3333-4444

没有结果。如果我搜索时没有连字符,我的书将按预期找到

我的设置如下:

{
  "analysis": {
    "filter": {
      "clean_special": {
        "type": "pattern_replace",
        "pattern": "[^a-zA-Z0-9]",
        "replacement": ""
      }
    },
    "analyzer": {
      "isbn_search_analyzer": {
        "type": "custom",
        "tokenizer": "keyword",
        "filter": [
          "clean_special"
        ]
      }
    }
  }
}
   @Field(type = FieldType.Keyword, searchAnalyzer = "isbn_search_analyzer")
   private String isbn;
   @Field(type = FieldType.Keyword, searchAnalyzer = "isbn_search_analyzer")
   private String ean;
GET indexname/_search
{
   "query": {
    "query_string": {
      "fields": [ "isbn", "ean" ],
      "query": "111-3333-444444"
    }
  }
}
我的字段索引如下:

{
  "analysis": {
    "filter": {
      "clean_special": {
        "type": "pattern_replace",
        "pattern": "[^a-zA-Z0-9]",
        "replacement": ""
      }
    },
    "analyzer": {
      "isbn_search_analyzer": {
        "type": "custom",
        "tokenizer": "keyword",
        "filter": [
          "clean_special"
        ]
      }
    }
  }
}
   @Field(type = FieldType.Keyword, searchAnalyzer = "isbn_search_analyzer")
   private String isbn;
   @Field(type = FieldType.Keyword, searchAnalyzer = "isbn_search_analyzer")
   private String ean;
GET indexname/_search
{
   "query": {
    "query_string": {
      "fields": [ "isbn", "ean" ],
      "query": "111-3333-444444"
    }
  }
}
如果我测试我的分析器:

GET indexname/_analyze
{
  "analyzer" : "isbn_search_analyzer",
  "text" : "111-3333-444444"
}
我得到以下结果:

{
  "tokens" : [
    {
      "token" : "1113333444444",
      "start_offset" : 0,
      "end_offset" : 15,
      "type" : "word",
      "position" : 0
    }
  ]
}
如果我像这样搜索:

{
  "analysis": {
    "filter": {
      "clean_special": {
        "type": "pattern_replace",
        "pattern": "[^a-zA-Z0-9]",
        "replacement": ""
      }
    },
    "analyzer": {
      "isbn_search_analyzer": {
        "type": "custom",
        "tokenizer": "keyword",
        "filter": [
          "clean_special"
        ]
      }
    }
  }
}
   @Field(type = FieldType.Keyword, searchAnalyzer = "isbn_search_analyzer")
   private String isbn;
   @Field(type = FieldType.Keyword, searchAnalyzer = "isbn_search_analyzer")
   private String ean;
GET indexname/_search
{
   "query": {
    "query_string": {
      "fields": [ "isbn", "ean" ],
      "query": "111-3333-444444"
    }
  }
}

我没有得到任何结果。有人知道吗?

Elasticsearch不分析类型为
关键字的字段。您需要将类型设置为
text

,正如@p.J.Meisch所提到的,您做的一切都是正确的,但是当您将字段数据类型定义为
关键字时,您没有将字段数据类型定义为
text
,即使您明确告诉ElasticSearch使用您的自定义分析器
isbn\u search\u analyzer
,它将被忽略

当字段定义为
text
时,示例数据的工作示例

索引映射

{
    "settings": {
        "analysis": {
            "filter": {
                "clean_special": {
                    "type": "pattern_replace",
                    "pattern": "[^a-zA-Z0-9]",
                    "replacement": ""
                }
            },
            "analyzer": {
                "isbn_search_analyzer": {
                    "type": "custom",
                    "tokenizer": "keyword",
                    "filter": [
                        "clean_special"
                    ]
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "isbn": {
                "type": "text",
                "analyzer": "isbn_search_analyzer"
            },
            "ean": {
                "type": "text",
                "analyzer": "isbn_search_analyzer"
            }
        }
    }
}
索引样本记录

{
    "isbn" : "111-3333-444444"
}

{
    "isbn" : "111-3333-2222"
}
搜索查询

{
    "query": {
        "query_string": {
            "fields": [
                "isbn",
                "ean"
            ],
            "query": "111-3333-444444"
        }
    }
}
和搜索响应

"hits": [
            {
                "_index": "65780647",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.6931471,
                "_source": {
                    "isbn": "111-3333-444444"
                }
            }
        ]

以前是“文本”,但也不起作用。我觉得字段映射被忽略了。@GoatMachine我看到你找到了解决方案:)如果你能在“文本”之前对我的答案(如果有帮助的话)进行投票,那就太好了:)但它也不起作用。我觉得FieldMapping被忽略了。映射是由Spring Data Elasticsearch创建的吗?Spring Data Elasticsearch仅在索引不存在时自动写入存储库的映射。或者如果显式使用
IndexOperations.putMapping()
,我认为Spring数据会自动执行,但我不知道为什么。我首先添加了
@字段
注释,现在我尝试使用mapping.json和
@mapping
注释。我手动创建索引,调用了
putMapping()
方法并删除了该语句。但是没有区别。在显示的
@字段中
使用中,您指定了一个
搜索分析器
,但没有指定索引期间要使用的分析器。因此,在存储数据时,将使用默认分析器,将ISBN拆分为令牌,在搜索时,您希望它不带连字符。我的输入ISBN不带连字符,因为我在将此数据存储到ElasticSearch之前删除了它。所以ElasticSearch收到的唯一东西就是一个文本。但是我也添加了一个索引分析器,没有什么区别。如果我打开Kibana并检查映射:每个字段都是文本类型,还有关键字。ean:Text ean.keyword:keyword isbn:Text isbn.keyword:keyword无论我指定什么作为映射