Algolia: как получить только первое вхождение поискового запроса в текстовое поле?
Я использую Algolia для добавления поиска на свой сайт JAMStack. однако на моем сайте есть какой-то премиум-контент, и я хочу, чтобы он был доступен для поиска, но оставался скрытым для пользователей.
Я могу добиться аналогичной функциональности, добавивbody
атрибут в доступные для поиска поля и удалите его из извлеченных атрибутов. таким образом, Algolia будет по-прежнему искать в теле вхождения запроса, не открывая их пользователю.
Но более предпочтительно, чтобы пользователь мог видеть одно или два вхождения того, что он искал, в извлеченном теле, но не мог видеть весь текст премиум-контента.
Например, предположим, что в нашем индексе есть следующие объекты:
[
{
title: "Hello",
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
},
{
title: "Hi",
body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit"
}
]
Теперь, если я запрашиваю API algolia с текстом "i", ответ algolia будет выглядеть так:
...
hits: [
{
title: "Hello",
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
_highlightResults: {
body: "Lorem <em>i</em>psum dolor s<em>i</em>t amet, consectetur ad<em>i</em>p<em>i</em>sc<em>i</em>ng el<em>i</em>t, sed do e<em>i</em>usmod tempor <em>i</em>nc<em>i</em>d<em>i</em>dunt ut labore et dolore magna al<em>i</em>qua. Ut en<em>i</em>m ad m<em>i</em>n<em>i</em>m ven<em>i</em>am, qu<em>i</em>s nostrud exerc<em>i</em>tat<em>i</em>on ullamco labor<em>i</em>s n<em>i</em>s<em>i</em> ut al<em>i</em>qu<em>i</em>p ex ea commodo consequat. Du<em>i</em>s aute <em>i</em>rure dolor <em>i</em>n reprehender<em>i</em>t <em>i</em>n voluptate vel<em>i</em>t esse c<em>i</em>llum dolore eu fug<em>i</em>at nulla par<em>i</em>atur. Excepteur s<em>i</em>nt occaecat cup<em>i</em>datat non pro<em>i</em>dent, sunt <em>i</em>n culpa qu<em>i</em> off<em>i</em>c<em>i</em>a deserunt moll<em>i</em>t an<em>i</em>m <em>i</em>d est laborum."
}
},
{
title: "Hi",
body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit",
_highlightResults: {
body: "Sed ut persp<em>i</em>c<em>i</em>at<em>i</em>s unde omn<em>i</em>s <em>i</em>ste natus error s<em>i</em>t voluptatem accusant<em>i</em>um doloremque laudant<em>i</em>um, totam rem aper<em>i</em>am, eaque <em>i</em>psa quae ab <em>i</em>llo <em>i</em>nventore ver<em>i</em>tat<em>i</em>s et quas<em>i</em> arch<em>i</em>tecto beatae v<em>i</em>tae d<em>i</em>cta sunt expl<em>i</em>cabo. Nemo en<em>i</em>m <em>i</em>psam voluptatem qu<em>i</em>a voluptas s<em>i</em>t aspernatur aut od<em>i</em>t aut fug<em>i</em>t, sed qu<em>i</em>a consequuntur magn<em>i</em> dolores eos qu<em>i</em> rat<em>i</em>one voluptatem sequ<em>i</em> nesc<em>i</em>unt. Neque porro qu<em>i</em>squam est, qu<em>i</em> dolorem <em>i</em>psum qu<em>i</em>a dolor s<em>i</em>t amet, consectetur, ad<em>i</em>p<em>i</em>sc<em>i</em> vel<em>i</em>t"
}
]
Но я хочу, чтобы он вернул следующее:
[
{
title: "Hello",
_highlightResults: {
body: "Lorem <em>i</em>psum dolor sit amet" // only the first occurance with some context
}
},
{
title: "Hi",
_highlightResults: {
body: "Sed ut persp<em>i</em>ciatis unde" // only the first occurance with some context
}
}
]
Я знаю, что нечто подобное можно сделать с помощью фрагментов, но если вы внимательно обратите внимание, поле body также удаляется из самого тела обращения, поэтому полное тело никогда не отправляется клиенту. Клиент может искать премиум-контент, пока сам контент не отображается.
Как я могу добиться этого с помощью API Algolia?
1 ответ
Вы должны иметь возможность реализовать такую логику с помощью сниппета. Вам не нужно возвращать поле для его поиска. Функция сниппета может контролировать, сколько контекста отправляется обратно с совпадением. Вы можете установить ограничение, чтобы возвращать только несколько слов, чтобы ограничить совпадение одним вхождением. Однако это не будет 100% точным, два совпадения могут быть возвращены, если они ближе, чем заданный предел (что не должно быть проблемой для реального варианта использования).
В приведенном ниже примере возвращается только name
атрибут для поиска. Вdescription
установлен в searchableAttributes
. Это означает, что запрос будет использовать этот атрибут для поиска. Это также означает, что мы можем использовать его с функцией сниппета. Здесь фрагмент ограничен 10 словами.
index.search('apple', {
attributesToRetrieve: ['name'],
attributesToSnippet: ['description:10'],
});
Обратите внимание, что эти значения устанавливаются во время поиска. Для реализации на стороне клиента это означает, что пользователь сможет изменять эти значения. Ваш вариант использования касается премиального контента, поэтому это проблематично. Чтобы обойти проблему, вы должны использовать ключ API с этими параметрами, записанными в нем. Вы не сможете изменить их во время поиска.