Elasticsearch Неверный регистр для неанализируемых документов
У меня есть тип со следующим отображением
PUT /testindex
{
"mappings" : {
"products" : {
"properties" : {
"category_name" : {
"type" : "string",
"index" : "not_analyzed"
}
}
}
}
}
Я хотел найти точное слово. Вот почему я установил это как not_analyzed.
Но проблема в том, что я хочу искать это в нижнем регистре или в верхнем регистре [регистр нечувствителен].
Я искал его и нашел способ установить нечувствительность к регистру.
curl -XPOST localhost:9200/testindex -d '{
"mappings" : {
"products" : {
"properties" : {
"category_name":{"type": "string", "index": "analyzed", "analyzer":"lowercase_keyword"}
}
}
}
}'
Есть ли способ сделать эти два сопоставления в одном поле.?
Спасибо..
Ответы
Ответ 1
Я думаю, что этот пример соответствует вашим потребностям:
$ curl -XPUT localhost:9200/testindex/ -d '
{
"settings":{
"index":{
"analysis":{
"analyzer":{
"analyzer_keyword":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
}
}
},
"mappings":{
"test":{
"properties":{
"title":{
"analyzer":"analyzer_keyword",
"type":"string"
}
}
}
}
}'
взято здесь: Как настроить токенизатор в elasticsearch
он использует как ключевой токенизатор, так и строчный фильтр в строковом поле, которое, я считаю, делает то, что вы хотите.
Ответ 2
Если вы хотите, чтобы запросы, не учитывающие регистр, ТОЛЬКО, подумайте об изменении как ваших данных, так и вашего запроса в нижнем/верхнем регистре до того, как вы начнете заниматься своим бизнесом.
Это означает, что вы сохраняете свое поле not_analyzed
и вводите данные/запрос только в одном из случаев.
Ответ 3
Я считаю, что этот Гист лучше всего отвечает на ваш вопрос:
* https://gist.github.com/mtyaka/2006966
Вы можете индексировать поле несколько раз во время сопоставления, и мы делаем это все время, когда один не_анализ, а другой. Обычно мы устанавливаем версию not_analyzed на .raw
Как писал Джон П., вы можете настроить анализатор во время выполнения, или вы можете установить его в конфигурации при запуске сервера, как в ссылке выше:
# Register the custom 'lowercase_keyword' analyzer. It doesn't do anything else
# other than changing everything to lower case.
index.analysis.analyzer.lowercase_keyword.type: custom
index.analysis.analyzer.lowercase_keyword.tokenizer: keyword
index.analysis.analyzer.lowercase_keyword.filter: [lowercase]
Затем вы определяете свое сопоставление для своего поля (ов) как с версией not_analyzed, так и с анализируемой:
# Map the 'tags' property to two fields: one that isn't analyzed,
# and one that is analyzed with the 'lowercase_keyword' analyzer.
curl -XPUT 'http://localhost:9200/myindex/images/_mapping' -d '{
"images": {
"properties": {
"tags": {
"type": "multi_field",
"fields": {
"tags": {
"index": "not_analyzed",
"type": "string"
},
"lowercased": {
"index": "analyzed",
"analyzer": "lowercase_keyword",
"type": "string"
}
}
}
}
}
}'
И, наконец, ваш запрос (обратите внимание на нижние значения перед построением запроса, чтобы найти совпадение):
# Issue queries against the index. The search query must be manually lowercased.
curl -XPOST 'http://localhost:9200/myindex/images/_search?pretty=true' -d '{
"query": {
"terms": {
"tags.lowercased": [
"event:battle at the boardwalk"
]
}
},
"facets": {
"tags": {
"terms": {
"field": "tags",
"size": "500",
"regex": "^team:.*"
}
}
}
}'
Ответ 4
просто создайте свой пользовательский анализатор с помощью токенизатора keyword
и lowercase
.
Ответ 5
В этих сценариях я предлагаю вам объединить lowercase filter
и keyword tokenizer
в свой собственный анализатор. И строчные ключевые слова для поиска.
1.Создайте индекс с помощью анализатора в сочетании с нижним регистром и ключевым словом tokenizer
curl -XPUT localhost:9200/test/ -d '
{
"settings":{
"index":{
"analysis":{
"analyzer":{
"your_custom_analyzer":{
"tokenizer":"keyword",
"filter": ["lowercase"]
}
}
}
}
}'
2. Отобразите отображения и задайте свойства поля с помощью analyzer
curl -XPUT localhost:9200/test/_mappings/twitter -d '
{
"twitter": {
"properties": {
"content": {"type": "string", "analyzer": "your_custom_analyzer" }
}
}
}'
3.Вы можете искать то, что хотите, в подстановочном запросе.
curl -XPOST localhost:9200/test/twitter/ -d '{
"query": {
"wildcard": {"content": "**the words you want to search**"}
}
}'
Другой способ поиска по-разному. Я полагаю, что предложение U - это использование типа multi_fields.
Вы можете установить поле в multi_field
curl -XPUT localhost:9200/test/_mapping/twitter -d '
{
"properties": {
"content": {
"type": "multi_field",
"fields": {
"default": {"type": "string"},
"search": {"type": "string", "analyzer": "your_custom_analyzer"}
}
}
}
}'
Таким образом, вы можете индексировать данные с указанными выше свойствами сопоставления. и, наконец, искать его двумя способами (default/your_custom_analyzer)
Ответ 6
Мы могли бы добиться нечувствительного к регистру поиска в незапрошенных строках с использованием сценариев ElasticSearch.
Пример запроса с использованием встроенных скриптов:
{
"query" : {
"bool" : {
"must" : [{
"query_string" : {
"query" : "\"apache\"",
"default_field" : "COLLECTOR_NAME"
}
}, {
"script" : {
"script" : "if(doc['verb'].value != null) {doc['verb'].value.equalsIgnoreCase(\"geT\")}"
}
}
]
}
}
}
Вам нужно включить скриптинг в файле elasticsearch.yml. Использование скриптов в поисковых запросах может снизить общую эффективность поиска. Если вы хотите, чтобы скрипты выполнялись лучше, вы должны сделать их "родными" с помощью java-плагина.
Пример кода плагина:
public class MyNativeScriptPlugin extends Plugin {
@Override
public String name() {
return "Indexer scripting Plugin";
}
public void onModule(ScriptModule scriptModule) {
scriptModule.registerScript("my_script", MyNativeScriptFactory.class);
}
public static class MyNativeScriptFactory implements NativeScriptFactory {
@Override
public ExecutableScript newScript(@Nullable Map<String, Object> params) {
return new MyNativeScript(params);
}
@Override
public boolean needsScores() {
return false;
}
}
public static class MyNativeScript extends AbstractSearchScript {
Map<String, Object> params;
MyNativeScript(Map<String, Object> params) {
this.params = params;
}
@Override
public Object run() {
ScriptDocValues<?> docValue = (ScriptDocValues<?>) doc().get(params.get("key"));
if (docValue instanceof Strings) {
return ((String) params.get("value")).equalsIgnoreCase(((Strings) docValue).getValue());
}
return false;
}
}
}
Пример запроса с использованием Native Script:
{
"query" : {
"bool" : {
"must" : [{
"query_string" : {
"query" : "\"apache\"",
"default_field" : "COLLECTOR_NAME"
}
}, {
"script" : {
"script" : "my_script",
"lang" : "native",
"params" : {
"key" : "verb",
"value" : "GET"
}
}
}
]
}
}
}
Ответ 7
это так просто, просто создайте сопоставление следующим образом
{
"mappings" : {
"products" : {
"properties" : {
"category_name" : {
"type" : "string"
}
}
}
}
}
Нет необходимости указывать индекс, если вы хотите работать с регистром нечувствительным, потому что индекс по умолчанию будет "стандартным", который будет заботиться о нечувствительности к регистру.
Ответ 8
Хотелось бы добавить комментарий, но я не могу. Поэтому ответ на этот вопрос " это невозможно".
Анализаторы состоят из одного Tokenizer и ноль или более TokenFilters.
Хотел бы я рассказать вам что-то еще, но потратив 4 часа на изучение этого ответа. Я в той же ситуации. Вы не можете пропустить токенизацию. Это либо все, либо выключено.