Как выполнить поиск по всем полям и вернуть каждый документ, содержащий этот поиск, в elasticsearch?

#elasticsearch #kibana #elastic-stack #elasticsearch-6

Вопрос:

У меня проблема с поиском в elasticsearch. У меня есть индекс с несколькими документами с несколькими полями. Я хочу иметь возможность выполнять поиск по всем полям, в которых выполняется запрос, и хочу, чтобы он возвращал все документы, содержащие значение, указанное в запросе. Я обнаружил, что использование simple_query_string хорошо работает для этого. Однако он не возвращает последовательных результатов. В моем индексе у меня есть документы с несколькими полями, содержащими даты. Например:

 "revisionDate" : "2008-01-01T00:00:00",
"projectSmirCreationDate" : "2008-07-01T00:00:00",
"changedDate" : "1971-01-01T00:00:00",
"dueDate" : "0001-01-01T00:00:00",
 

Это всего лишь несколько примеров, однако, когда я индексирую, например:

 GET new_document-20_v2/_search
{
  "size": 1000, 
  "query": {
    "simple_query_string" : {
        "query": "2008"
    }
  }
}
 

Он возвращает только два документа, это проблема, потому что у меня гораздо больше документов, чем просто два, которые содержат значение «2008» в своих полях.

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

 "fileName" : "testPDF.pdf",
"fileName" : "demo.pdf",
"fileName" : "demo.txt",
 

Когда я спрашиваю:

 GET new_document-20_v2/_search
{
  "size": 1000, 
  "query": {
    "simple_query_string" : {
        "query": "demo"
    }
  }
}
 

Я не получаю никаких результатов
Но если я спрошу:

 GET new_document-20_v2/_search
{
  "size": 1000, 
  "query": {
    "simple_query_string" : {
        "query": "demo.txt"
    }
  }
}
 

Я получаю правильный результат.

Есть ли лучший способ поиска по всем документам и полям, чем я сделал? Я хочу, чтобы он возвращал весь документ, соответствующий запросу, а не только два или ноль. Любая помощь была бы очень признательна.

Комментарии:

1. Не могли бы вы поделиться своим отображением индекса ?

2. если вы не укажете поле multi_match (и в вашем индексе не задано поле поиска по умолчанию), он выполнит поиск по всем доступным для поиска полям multi_match docs

3. @ESCoder отображение немного велико, так что вот «justpaste.it» ссылка jpst.it/2uuTT

4. @Nate по multi_match -прежнему возвращает только два документа при запросе «2008»

Ответ №1:

Elasticsearch использует стандартный анализатор, если анализатор не указан. Поскольку анализатор не указан "fileName" , demo.txt он маркируется на

 {
  "tokens": [
    {
      "token": "demo.txt",
      "start_offset": 0,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 0
    }
  ]
}
 

Теперь, когда вы ищете demo , это не даст никакого результата, но поиск demo.txt даст результат.


Вместо этого вы можете использовать запрос с подстановочными знаками для поиска документа, имеющего demo в fileName

 {
  "query": {
    "wildcard": {
      "fileName": {
        "value": "demo*"
      }
    }
  }
}
 

Результатом поиска будет

 "hits": [
      {
        "_index": "67303015",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "fileName": "demo.pdf"
        }
      },
      {
        "_index": "67303015",
        "_type": "_doc",
        "_id": "3",
        "_score": 1.0,
        "_source": {
          "fileName": "demo.txt"
        }
      }
    ]
 

Так revisionDate как , projectSmirCreationDate , changedDate , dueDate все имеют тип date , поэтому вы не можете выполнить частичный поиск по этим датам.

Вы можете использовать несколько полей, чтобы добавить еще одно поле ( text типа) в вышеуказанные поля. Измените сопоставление индексов, как показано ниже

 {
  "mappings": {
    "properties": {
      "changedDate": {
        "type": "date",
        "fields": {
          "raw": {
            "type": "text"
          }
        }
      },
      "projectSmirCreationDate": {
        "type": "date",
        "fields": {
          "raw": {
            "type": "text"
          }
        }
      },
      "dueDate": {
        "type": "date",
        "fields": {
          "raw": {
            "type": "text"
          }
        }
      },
      "revisionDate": {
        "type": "date",
        "fields": {
          "raw": {
            "type": "text"
          }
        }
      }
    }
  }
}
 

Данные Индекса:

 {
  "revisionDate": "2008-02-01T00:00:00",
  "projectSmirCreationDate": "2008-02-01T00:00:00",
  "changedDate": "1971-01-01T00:00:00",
  "dueDate": "0001-01-01T00:00:00"
}
{
  "revisionDate": "2008-01-01T00:00:00",
  "projectSmirCreationDate": "2008-07-01T00:00:00",
  "changedDate": "1971-01-01T00:00:00",
  "dueDate": "0001-01-01T00:00:00"
}
 

Поисковый запрос:

 {
  "query": {
    "multi_match": {
      "query": "2008"
    }
  }
}
 

Результат поиска:

 "hits": [
      {
        "_index": "67303015",
        "_type": "_doc",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "revisionDate": "2008-01-01T00:00:00",
          "projectSmirCreationDate": "2008-07-01T00:00:00",
          "changedDate": "1971-01-01T00:00:00",
          "dueDate": "0001-01-01T00:00:00"
        }
      },
      {
        "_index": "67303015",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.18232156,
        "_source": {
          "revisionDate": "2008-02-01T00:00:00",
          "projectSmirCreationDate": "2008-02-01T00:00:00",
          "changedDate": "1971-01-01T00:00:00",
          "dueDate": "0001-01-01T00:00:00"
        }
      }
    ]
 

Комментарии:

1. @Сандер Маркс, пожалуйста, просмотрите приведенный выше ответ и дайте мне знать, решит ли это вашу проблему ?

2. После изменения моего отображения индекса, как вы показали, он работал так, как я хочу! Большое вам спасибо!