autosuggest query for elastic
amarflybot18 opened this issue · comments
Amarendra Kumar commented
Hi @nodkz , Do you have support for autosuggest query?
Amarendra Kumar commented
This is especially related to the Elastic Suggester: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#completion-suggester
Paul Damnhorns commented
Nope, I didn't find a general solution.
So I recommend creating suggest resolver manually. Something like this:
export const addSuggestR = <TSource, TContext>(
TC: ObjectTypeComposer<TSource, TContext>
): ObjectTypeComposer<TSource, TContext> => {
return TC.addResolver({
name: 'suggest',
kind: 'query',
type: [
TC.schemaComposer.createObjectTC({
name: `${TC.getTypeName()}SuggestType`,
fields: {
_id: 'String',
score: 'Float',
...TC.getFields(),
},
}),
],
args: {
q: 'String',
limit: 'Int',
popular: 'Boolean',
},
resolve: async ({ args }) => {
const { q, limit, popular } = args || {};
const suggestBody = {
query: {
bool: {
should: [
// match regular title
{
match: {
title: {
query: q,
boost: 6,
fuzziness: 'auto',
},
},
},
// match inverse_keyboard title
{
match: {
title: {
query: q,
analyzer: 'search_analyzer_inverse_keyboard',
boost: 5,
fuzziness: 'auto',
},
},
},
// match regular _all
{
match: {
_all: {
query: q,
boost: 4,
fuzziness: 'auto',
},
},
},
// match inverse_keyboard _all
{
match: {
_all: {
query: q,
analyzer: 'search_analyzer_inverse_keyboard',
boost: 3,
fuzziness: 'auto',
},
},
},
// match regular synonyms
{
match: {
synonyms: {
query: q,
boost: 2,
fuzziness: 'auto',
},
},
},
// match inverse_keyboard synonyms
{
match: {
synonyms: {
query: q,
analyzer: 'search_analyzer_inverse_keyboard',
fuzziness: 'auto',
},
},
},
],
minimum_should_match: 1,
},
},
_source: true,
size: limit || 10,
};
const suggestPopularBody = {
query: {
range: {
popular: {
gt: 0,
},
},
},
sort: [{ popular: { order: 'desc' } }],
_source: true,
size: limit || 10,
};
const res = await elasticClient.search({
index: 'dic',
type: generateESType(TC.getTypeName()), // Model.modelName
body: popular ? suggestPopularBody : suggestBody,
});
if (res?.hits?.hits?.length > 0)
return res.hits.hits.map(item => {
return {
_id: item._id,
score: item._score,
...item._source,
};
});
return [];
},
});
};
Amarendra Kumar commented
Thanks a lot.