LINUX.ORG.RU

Как в PostgresQL сделать fuzzy search по jsonb колонке

 , , ,


1

1

есть колонка data, в ней лежит json, по этому json нужно сделать поиск. само собой json не особо структурирован. так что привязатся к конкретным ключам не получится. pg_trgm стоит, но если я пробую сделать как рекомендует chatГопоты, а именно:

SELECT * FROM your_table WHERE data::text % ‘search_term’;

This approach converts the JSONB data to text and then uses trigram matching for fuzzy search.

То это не работает, и просто возвращает пустой массив.

С fuzzy search в постгресе я мало знаком, так что подскажите плез что я делаю не так.

where data::text like ‘%First%’

Вот так работает, но мне нужно чтобы еще работало когда юзер например опечатался. Т.е ввел не First а Fist, или Frst. Нужен именно нечеткий поиск по триграммам



Последнее исправление: Unixson (всего исправлений: 4)

То это не работает, и просто возвращает пустой массив

Так у тебя наверное там большой жсон. Твой матч «First» будет капля в море по сравнению с всем текстом. Поэтому similarity будет очень низким, меньше порога.

Попробуй на одной записи в таблице, которая точно должна матчиться, посмотреть какое получается значение similarity.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

ну я бы не сказал что там сильно большой жисон, но видимо да similarity меньше порога, поэтому и не работает.

Попробуй на одной записи в таблице, которая точно должна матчиться, посмотреть какое получается значение similarity.

0.0882353 similarity. Что с этим можно сделать?

В жсоне максимум 15 ключ-значений без вложенности. Каждой значение это строка. Аля { «a»: «b», «c»: «d», … } т.е никакой мудренной структуры

Unixson
() автор топика
Последнее исправление: Unixson (всего исправлений: 3)
Ответ на: комментарий от Unixson

что-нибудь типа такого:

SELECT
	*
FROM
	table1 t
	LEFT JOIN LATERAL (
		SELECT tw.w FROM regexp_split_to_table(t.jb_data::text, '[^A-Za-z0-9]+') AS tw(w)
	) x ON TRUE
WHERE 
	x.w::text % 'frst'
;
вручную порезать на слова (не обязательно как тут), и каждое слово сравнивать.

Toxo2 ★★★★
()
Последнее исправление: Toxo2 (всего исправлений: 1)
Ответ на: комментарий от Toxo2

надо пробовать, но вроде так должно работать. странно конечно, я вроде делаю индекс

CREATE INDEX your_table_data_trgm_idx ON your_table USING gin((data::text) gin_trgm_ops);

А блин все равно он не индексируется по нормальному

Unixson
() автор топика