Как выполнить Elastic Search Term Query с помощью Analyzer и двух параметров в Java API

Я новичок в Elastic Search, я интегрирую его с MongoDB для индексации и поиска данных.

Все это работает нормально, и я строю индексы, используя следующий пример:

    curl -XPUT localhost:9200/test/newperson/1 -d '{
  "type": "mongodb",
  "mongodb": {
    "servers": [
      { "host": "pc-4372", "port": 27017 }
    ],
    "db": "newPerson",
    "collection": "Person",
    "options": { "secondary_read_preference": true },
    "gridfs": false
   },
  "index": {
    "name": "mongoIndex",
    "type": "Person"
  }
}'

В настоящее время я создаю веб-сервис, который будет использовать Java API для выполнения необходимых поисковых запросов.

Мне нужно искать во встроенном индексе с двумя одинаковыми значениями "запрос запроса". Я знаю, что для срочных запросов нам нужно использовать анализаторы для анализа текста и иметь возможность получать идентичные значения.

Я пробовал несколько способов построения индекса и определения анализаторов для определенных полей, но не смог. Также я попытался сделать это с уровня Java API, и он отлично работает, но только для одного поля я не смог сделать это с двумя полями.

 SearchResponse r1 = client.prepareSearch("rootcause")
                    .setQuery(QueryBuilders.queryString("_id:" + rc.getRootCause_ID()).analyzer("snowball"))
                    .execute() 
                    .actionGet();

Я создаю прототип для диагностики сбоев некоторых устройств,

Я хочу выполнить поиск по модели устройства и симптому, введенному пользователем. Я пробовал также следующий код:

    SearchResponse response = client.prepareSearch("modelsymptom")
            .setQuery(QueryBuilders.queryString("model_id: " + "MO-1" + " AND " + "symptom: RC-4").analyzer("snowball"))
            .execute()
            .actionGet();

Полученные результаты из вышеупомянутого запроса содержат все документы с RC-4 или MO-1 и другие, что является неправильным. Этот запрос должен получить только один результат.

Что лучше: создать индекс с помощью предписанного анализатора или сделать это на уровне Java API?

Насколько я понимаю, я думаю, что было бы лучше построить анализатор с индексом, но пока не знаю, как это сделать.

2 ответа

Решение

Я знаю, что для срочных запросов нам нужно использовать анализаторы для анализа текста и иметь возможность получать идентичные значения.

Это не правильно.

В то время как полнотекстовые запросы будут анализировать строку запроса перед выполнением, запросы на уровне терминов работают с точными терминами, которые хранятся в инвертированном индексе.

При запросе полнотекстовых полей используйте вместо этого запрос на совпадение, который понимает, как было проанализировано поле.

В противном случае у вас будут проблемы, описанные здесь: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

Что лучше: создать индекс с помощью предписанного анализатора или сделать это на уровне Java API?

В любом случае, это зависит от вашего конкретного сценария.

Вы можете создать индекс с помощью анализатора из Java, если хотите.

String analyser = "{...}";

CreateIndexRequestBuilder createIndexRequestBuilder = 
    client.admin().indices().prepareCreate("indexName");
createIndexRequestBuilder.setSettings(analyser);
createIndexRequestBuilder.execute().actionGet();

Где ваш анализатор что-то вроде:

{
    "analysis": 
    {    
        "analyzer": 
        {
            "my_analiser": 
            {
                "type": "english"
            }
        }
    }
}

Но тогда вам нужно будет создать собственное отображение и указать там анализатор.

Если вы не укажете свое собственное отображение, когда Elasticsearch обнаружит новое строковое поле в ваших документах, он автоматически настроит его как полнотекстовое строковое поле и проанализирует его с помощью стандартного анализатора. Это может быть достаточно для вас, но обычно это не так, и вам нужно создать свое собственное отображение. Вы можете сделать это и с Java.

// Index (and mapping) do not exist
CreateIndexRequestBuilder createIndexRequestBuilder = 
  client.admin().indices().prepareCreate("indexName");
createIndexRequestBuilder.addMapping("typeName", mapping);
response = createIndexRequestBuilder.execute().actionGet();

// Index exists but not mapping
PutMappingRequestBuilder preparePutMappingBuilder = 
  client.admin().indices().preparePutMapping("indexName");
preparePutMappingBuilder.setSource(mapping).setType("typeName");
response = preparePutMappingBuilder.execute().actionGet();

Как выполнить Elastic Search Term Query с помощью Analyzer и двух параметров в Java API

Вы можете объединить два запроса с терминами, используя составной запрос, такой как логический запрос:

Или используйте запрос условий:

Но согласно тому, что вы описали здесь, если вам действительно нужно использовать анализируемый текст, вам, скорее всего, понадобится запрос с несколькими совпадениями или логический запрос с двумя запросами на совпадение.

MultiMatchQueryBuilder queryBuilder = 
   new MultiMatchQueryBuilder("foo", "fieldOne", "fieldTwo");
client.prepareSearch()
     .setIndices(index)
     .setQuery(queryBuilder)
     .execute().actionGet();

Или же:

QueryBuilder firstQueryBuilder = QueryBuilders.matchQuery("fieldOne", "foo");
QueryBuilder secondQueryBuilder = QueryBuilders.matchQuery("fieldTwo", "foo");
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(firstQueryBuilder);
boolQueryBuilder.must(secondQueryBuilder);
client.prepareSearch()
     .setIndices(index)
     .setQuery(queryBuilder)
     .execute().actionGet();

Надеюсь это поможет.

Вам не нужен специальный анализатор, просто используйте запрос bool с "must" и двумя терминами. А "простой запрос" существует в основном для проверки запросов вручную, я бы не использовал его в коде. Также всегда сначала пробуйте свои запросы с REST API.

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "model": "XXXX",
          }
        },
        {
          "term": {
            "symptom": "YYYY" 
          }
        }
      ]
    }
  }
}

Другие вопросы по тегам