У меня следующая проблема: я храню книги в эластичной базе данных. Важно, чтобы каждое слово сохранялось как отдельная запись , потому что оно содержит определенные метаданные, которые мне нужны. Книги относятся к категориям, книга может принадлежать к одной или нескольким категориям, и это изменяемое свойство (отношения книги и категории также сохраняются в MySQL). Ожидаемое количество книг - пара тысяч. Мне нужен быстрый поиск по всем книгам по слову (например, кто-то ищет слово «тест», мне нужно найти книги, которые содержат это слово и на каких страницах.). Можно также ограничить поиск по категории.
Моя дилемма заключается в том, чтобы сохранять слова для книги во вложенных полях, например
{
"book_name": "book1",
"book_categories": ["cat1", "cat2", ...],
"book_words": [
{
"some_word_meta": "...",
"page": 1
"word_value": "word1"
},
{
"some_word_meta": "...",
"page": 1
"word_value": "word2"
} ... lots of these
]
},
{
"book_name": "book2",
"book_categories": ["cat5", "cat6"],
"book_words": [
{
"some_word_meta": "...",
"page": 1,
"word_value": "wordx"
}, ... lots of these
]
}
В приведенном выше примере, еслиЯ перемещаю книгу из одной категории в другую, мне просто нужно обновить 1 запись в эластичном. Повлияет ли это вложение на производительность поиска?
Я также не могу сохранять информацию о категориях в эластичном формате и всегда передавать имена книг в запросе (поскольку MySQL знает, какие книги входят в категорию), но затемЯ бы хотел что-то подобное в поисковом запросе: book_name in ["book1", "book2", ... thousands more] and word == 'wordx'
. В этом случае книги могут быть сведены:
{
"book_name": "book1",
"page": 1,
"word_value": "word1",
"some_word_meta: "..."
},
{
"book_name": "book1",
"page": 1,
"word_value": "word2",
"some_word_meta: "..."
}
Существует много повторений данных, каждое слово знает, к какой книге оно принадлежит, и поисковый запрос кажется ужасным.
Яэто довольно плохо знакомо сasticsearch, и у меня до сих пор нет набора данных, чтобы попробовать его, какое из этих решений, скорее всего, сработает, или есть какое-то другое решение, о котором я не подумал?