ElasticSearch извлекает только элементы списка, которые соответствуют термину в одном документе.

Учитывая эту структуру документа.

{
   "title":"Lord of the rings",
   "id":"123abc",
   "pages":[
      {
         "pageNumber":1,
         "content":"Lorem ipsum lorem ipsum lorem ipsum"
      },
      {
         "pageNumber":2,
         "content":"dolor sit dolor sit dolor sit"
      }
   ]
}

и этот запрос

{
   "query":{
      "match":{
         "pages.content":"lorem"
      }
   }
}

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

{
   "title":"Lord of the rings",
   "id":"123abc",
   "pages":[
      {
         "pageNumber":1,
         "content":"Lorem ipsum lorem ipsum lorem ipsum"
      }
   ]
}

Значит, если у меня сотни страниц, я получу только те, которые соответствуют моему запросу?

Я думал о создании индекса для страниц, но как мне получить все метаданные из документа? Следует ли копировать эти метаданные во все страницы документа, скажем, из одной "книги"? Какой лучший подход с точки зрения производительности?

1 ответ

Да, документы с общими метаданными - это нормально (и часто необходимо) в хранилищах данных NoSQL. Что касается альтернативного подхода, вы можете использовать выделение или даже безболезненный сценарий, но я бы рекомендовал что-то вроде:

POST pages/_doc
{
  "book": {
    "title": "Lord of the rings",
    "id": "123abc",
    "metadata": {
      "num_of_pages": 300
    }
  },
  "page": {
    "pageNumber": 1,
    "content": "Lorem ipsum lorem ipsum lorem ipsum"
  }
}

POST pages/_doc
{
  "book": {
    "title": "Lord of the rings",
    "id": "123abc",
    "metadata": {
      "num_of_pages": 300
    }
  },
  "page": {
    "pageNumber": 2,
    "content": "dolor sit dolor sit dolor sit"
  }
}

А потом

GET pages/_search
{
  "query": {
    "match": {
      "page.content": "lorem"
    }
  }
}

который намного проще и достаточно хорошо масштабируется.

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