» »

[MariaDB] Kolikokrat se pojavi tekst v tekstu?

[MariaDB] Kolikokrat se pojavi tekst v tekstu?

HotBurek ::

Pozdravljeni.


Zanima me kakšni so načini za rešitev tele zagonetke.

V stolpcu tipa TEXT je sledeč vrednost: "abba baba babuška"

Kako s querijem dobiti število, kolikokrat se ponovi "ba"? Tako, da vrne 4.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

WizzardOfOZ ::

Declare @string varchar(1000)

DECLARE @SearchString varchar(100)

Set @string = 'abba baba babuška'

SET @SearchString = 'ba'

select ((len(@string) - len(replace(@string, @SearchString, ''))) -(len(@string) - 
        len(replace(@string, @SearchString, ''))) % 2)  / len(@SearchString)


http://dataeducation.com/counting-occur...

Zgodovina sprememb…

HotBurek ::

Hvala za sample.


Sem dodal v večjo skripto, a so nekje še nepravilnosti...

Prvi primer; če iščem po "CREATIVE%20WORKSHOP", mi za count vrača ne cela štrevila (a ne za vse search term-e).


Drug problem pa je, kako pri branju iz baze konvertat "%20" v space (in vse ostale).

Ker trenutno, če iščem po "a", mi najde tudi "%C5%A1", ki je sicer "š" (to bom verjetno pofixal pri klicu procedure in konvertal string...).



SET @searchfor = LOWER('CREATIVE%20WORKSHOP');

SELECT `adrank`.`id` AS 'id',
	MAX(`adrank`.`rankt`) AS 'rankt',
	MAX(`adrank`.`rankd`) AS 'rankd',
	MAX(`adrank`.`rankt`) + MAX(`adrank`.`rankd`) AS 'rank',
	`adcount`.`countt` AS 'countt',
	`adcount`.`countd` AS 'countd',
	`adcount`.`count` AS 'count',
	`adrank`.`title` AS 'title',
	`adrank`.`description` AS 'description'
FROM (
	SELECT `ad00`.`id`, 4 AS 'rankt', 0 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`title`) LIKE @searchfor
	UNION
	SELECT `ad00`.`id`, 3 AS 'rankt', 0 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`title`) LIKE (CONCAT(@searchfor, '%'))
	UNION
	SELECT `ad00`.`id`, 2 AS 'rankt', 0 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`title`) LIKE (CONCAT('%', @searchfor))
	UNION
	SELECT `ad00`.`id`, 1 AS 'rankt', 0 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`title`) LIKE (CONCAT('%', @searchfor, '%'))
	UNION
	SELECT `ad00`.`id`, 0 AS 'rankt', 4 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`description`) LIKE @searchfor
	UNION
	SELECT `ad00`.`id`, 0 AS 'rankt', 3 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`description`) LIKE (CONCAT(@searchfor, '%'))
	UNION
	SELECT `ad00`.`id`, 0 AS 'rankt', 2 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`description`) LIKE (CONCAT('%', @searchfor))
	UNION
	SELECT `ad00`.`id`, 0 AS 'rankt', 1 AS 'rankd', `ad00`.`title`, `ad00`.`description`
	FROM `aaa`.`Ad00` AS `ad00`
	WHERE LOWER(`ad00`.`description`) LIKE (CONCAT('%', @searchfor, '%'))
) AS `adrank`
INNER JOIN (
	SELECT
		`ad00`.`id`,
		(
			(LENGTH(`ad00`.`title`) - LENGTH(REPLACE(LOWER(`ad00`.`title`), @searchfor, '')))
			-
			(LENGTH(`ad00`.`title`) - LENGTH(REPLACE(LOWER(`ad00`.`title`), @searchfor, '')))
			% 2)
		/
		LENGTH(@searchfor) AS 'countt',
		(
			(LENGTH(`ad00`.`description`) - LENGTH(REPLACE(LOWER(`ad00`.`description`), @searchfor, '')))
			-
			(LENGTH(`ad00`.`description`) - LENGTH(REPLACE(LOWER(`ad00`.`description`), @searchfor, '')))
			% 2)
		/
		LENGTH(@searchfor) AS 'countd',
		((
			(LENGTH(`ad00`.`title`) - LENGTH(REPLACE(LOWER(`ad00`.`title`), @searchfor, '')))
			-
			(LENGTH(`ad00`.`title`) - LENGTH(REPLACE(LOWER(`ad00`.`title`), @searchfor, '')))
			% 2)
		/
		LENGTH(@searchfor))
		+
		((
			(LENGTH(`ad00`.`description`) - LENGTH(REPLACE(LOWER(`ad00`.`description`), @searchfor, '')))
			-
			(LENGTH(`ad00`.`description`) - LENGTH(REPLACE(LOWER(`ad00`.`description`), @searchfor, '')))
			% 2)
		/
		LENGTH(@searchfor)) AS 'count'
	FROM `aaa`.`Ad00` AS `ad00`
) AS `adcount`
ON `adrank`.`id` = `adcount`.`id`
GROUP BY `adrank`.`id`;
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

BigWhale ::

A je to nekaj kar moras nujno poceti z bazo? Ker tole je sila nerodno in bo na dolgi rok zamudno. V pythonu je to en klic...

>>> a = "abba baba babuška"
>>> a.count('ba')
4


Ce imas %20 na mesto presledka v bazi potem je v bazi zapisan urlencoded text. To je narobe iz veliko razlogov in bi bilo najbolje najprej odpraviti to in narediti neko normalizacijo podatkov. Brez tega je karkoli bolj resnega skoraj nesmiselno delati.

HotBurek ::

To, da je nujno pocet z bazo, ni. Nekako se nagibam (po videnih komplikacijah), da bo to (search, rank) v middleware-u (Python), kjer se bodo rezultati keširal v memcached (tega uporabljam sedaj, lahko se postavi drug cache sistem). Ampak še nisem tako daleč. Sedaj raziskujem, kako rešit search po dveh stolpcih, kjer nekdo na frontend-u vnese "tekst" in da potem dobi neke relevantne zadetke nazaj.

Kar se urlencoded tiče; Ja, na client strani JS naredi encodeURIComponent, in takšna string vrednost se potem shrani v tabelo. Lahko v Python-u to spremenim. Oz. če pravite, da je narobe, pol že ni optimalno...
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

BigWhale ::

No, seveda je vse odvisno od tega kaj tocno rabis in zakaj bi to rad pocel. Implementacija na strani bazi ni vedno zgresena ampak moras za to imeti dost dober case, da upravicis taksno stvar.

Kar se tice urlencoded stringov, je IMO bolje, da jih imas v bazi v izvirni obliki, zato da kadarkoli kasneje ne pride do zmesnjav. Urlencoded stvari uporabljas samo takrat, ko jih transportiras naokrog. Zapisujes jih pa potem v utf8 ali pa celo utf16, ce je potreba. V nasprotnem primeru bos prej ali slej naletel na tezavo, ko bos nek urlencoded string primerjal s klasicnim stringom in se bos cohal in ugotavljal zakaj rec ne deluje.

HotBurek ::

Evo update. Sem naredil tako, da kot Python dobi od JS string, naredi urllib.parse.unquote("encodeURIComponent input from JS") in potem to zapiše v tabelo.

Sedaj dela klasičen WHERE MATCH (columns) AGAINS ("+search ford* -this" IN BOOLEAN MODE) bistveno bolje. Fora je, da so prej presledki bili "%20" in je vse skupaj bil en dolgi string. Sedaj, ko so besede ločene s presledkom, išče bistveno bolje.

Sem pa opazil, da se namesto dvopščje : shrani string ":".
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

BigWhale ::

Lahk nardis uporabis se html.unescape(), pa ti odstrani se HTML entities iz stringov.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Slo-Tech userscripts

Oddelek: Izdelava spletišč
175198 (2650) jype
»

SQL vprasanje (strani: 1 2 )

Oddelek: Programiranje
688413 (5092) BivšiUser2
»

12v napajalnik za LED trak za v dozo- obstaja?

Oddelek: Elektrotehnika in elektronika
6996 (772) Invictus
»

počasno delovanje kompa Asus N76VZ

Oddelek: Pomoč in nasveti
81190 (1018) WIngs
»

MS Access (strani: 1 2 )

Oddelek: Programiranje
647439 (5497) travica

Več podobnih tem