Avatar billede AnyFellow Mester
17. november 2017 - 19:25 Der er 17 kommentarer og
1 løsning

Fritekstsøgning i flere poster, der hører til samme identitet

Jeg har en tabel med en masse rækker. Hver række har et brugerid. Et brugerid kan være tilknyttet mange rækker.

Jeg vil gerne lave mulighed på min side for at fritekstsøge i rækkerne men kan ikke gennemskue hvordan der gøres smartest.

Hvis jeg f.eks. søger på 3 ord, vil jeg gerne ende med en udtræk over de brugerid’er, hvor de 3 ord indgår i en eller flere poster.

Kan det gøres fornuftigt i én forespørgsel?

Antallet af søgeord er op til den der søger.
Avatar billede jakobdo Ekspert
17. november 2017 - 20:36 #1
Måske du kunne kigge på FULL TEXT SEARCH: https://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html
Avatar billede AnyFellow Mester
17. november 2017 - 21:41 #2
Det kender jeg ikke. Prøve at læse om det i morgen og vender tilbage.
Avatar billede AnyFellow Mester
18. november 2017 - 08:33 #3
Jeg kan ikke umiddelbart se, hvordan det skulle kunne løse min problemstilling.

Min tabel kan f.eks. se således ud:

----------------------------------------
| ID | USERID | TEXT                  |
----------------------------------------
| 1  | 1      | bla bla Tekst1 bla bla |
| 2  | 1      | bla bla Tekst2 bla bla |
| 3  | 1      | bla bla Tekst3 bla bla |
| 4  | 2      | bla bla Tekst1 bla bla |
| 5  | 2      | bla bla Tekst2 bla bla |
| 6  | 2      | bla bla Tekst4 bla bla |
| 7  | 3      | bla bla Tekst4 bla bla |
| 8  | 3      | bla bla Tekst5 bla bla |
| 9  | 3      | bla bla Tekst6 bla bla |
| 10 | 4      | bla bla Tekst1 bla bla |
| 11 | 4      | bla bla Tekst3 bla bla |
| 12 | 4      | bla bla Tekst2 bla bla |
----------------------------------------


Hvis jeg søger på 'Tekst1', 'Tekst2', og 'Tekst3', skal userid 1 og 4 returneres.
Hvis jeg søger på 'Tekst1', og 'Tekst2', skal userid 1,2 og 4 returneres.

En søgning som denne:

SELECT `userid`
FROM `table`
WHERE `text` like '%Tekst1%'
OR `text` like '%Tekst2%'
OR `text` like '%Tekst3%'
GROUP BY `user`

vil returnere userid 1,2,3 og 4
Avatar billede jakobdo Ekspert
19. november 2017 - 13:33 #4
Hvad er der galt med din SQL herover ?
Avatar billede AnyFellow Mester
20. november 2017 - 08:03 #5
Problemet er at min SQL returnerer userid 1,2,3 og 4.

Den skulle gerne kun returnere 1 og 4, da det er de eneste userids, der har poster med alle tre søgeord.

Umiddelbart tænker jeg, at jeg nok må bruge UNION, men havde håber der var noget knap så belastende for serveren.
Avatar billede AnyFellow Mester
20. november 2017 - 10:19 #6
Umiddelbart ser denne ud til at løse mit problem:

SELECT `userid`
FROM `table`
WHERE `text` like '%Tekst1%'
OR `text` like '%Tekst2%'
OR `text` like '%Tekst3%'
GROUP BY `userid`
HAVING COUNT(*)=3
Avatar billede AnyFellow Mester
20. november 2017 - 15:21 #7
Hmm, efter yderligere tests, kan jeg se at den ikke fungerer 100% som jeg ønsker.

Er f.eks. "Tekst1" og "Tekst2" i samme række vil count'en være én for lav.

Nogen idé til hvordan jeg kan løse dette?
Avatar billede jakobdo Ekspert
20. november 2017 - 17:14 #8
Jeg skal lige have sat en test database op, så skal jeg forsøge at lege lidt med det senere
Avatar billede AnyFellow Mester
20. november 2017 - 18:55 #9
Det lyder godt. Jeg kan ikke gennemskue hvordan jeg løser det, ud over at lave x forespørgsler, afhængig af antallet af søgeord.
Avatar billede jakobdo Ekspert
20. november 2017 - 20:27 #10
Kan du ikke bruge noget ala dette:

SELECT userid FROM `tabel_navn` WHERE `text` REGEXP 'Tekst1|Tekst2|Tekst3' GROUP BY userid
Avatar billede AnyFellow Mester
21. november 2017 - 07:02 #11
Desværre, den finder 1,2, og 4, hvor den kun burde finde 1 og 4.
Avatar billede jakobdo Ekspert
21. november 2017 - 07:20 #12
Så tror jeg desværre ikke jeg ved hvad du ønsker...

Du skriver:

Hvis jeg f.eks. søger på 3 ord, vil jeg gerne ende med en udtræk over de brugerid’er, hvor de 3 ord indgår i en eller flere poster.

Du har data:

----------------------------------------
| ID | USERID | TEXT                  |
----------------------------------------
| 1  | 1      | bla bla Tekst1 bla bla |
| 2  | 1      | bla bla Tekst2 bla bla |
| 3  | 1      | bla bla Tekst3 bla bla |
| 4  | 2      | bla bla Tekst1 bla bla |
| 5  | 2      | bla bla Tekst2 bla bla |
| 6  | 2      | bla bla Tekst4 bla bla |
| 7  | 3      | bla bla Tekst4 bla bla |
| 8  | 3      | bla bla Tekst5 bla bla |
| 9  | 3      | bla bla Tekst6 bla bla |
| 10 | 4      | bla bla Tekst1 bla bla |
| 11 | 4      | bla bla Tekst3 bla bla |
| 12 | 4      | bla bla Tekst2 bla bla |
----------------------------------------

Og hvis man søger på Tekst1,2 og 3, så matcher den jo:

| 1  | 1      | bla bla Tekst1 bla bla |
| 2  | 1      | bla bla Tekst2 bla bla |
| 3  | 1      | bla bla Tekst3 bla bla |
| 4  | 2      | bla bla Tekst1 bla bla |
| 5  | 2      | bla bla Tekst2 bla bla |
| 10 | 4      | bla bla Tekst1 bla bla |
| 11 | 4      | bla bla Tekst3 bla bla |
| 12 | 4      | bla bla Tekst2 bla bla |

Der ser jeg da både 1, 2 og 4 som USERID.
Avatar billede acore Ekspert
21. november 2017 - 08:16 #13
Hvad med

SELECT * FROM
(
SELECT `userid` FROM `table` WHERE `text` like '%Tekst1%'
UNION
SELECT `userid` FROM `table` WHERE `text` like '%Tekst2%'
UNION
SELECT `userid` FROM `table` WHERE `text` like '%Tekst3%'
)
GROUP BY `userid`
HAVING COUNT(*)>=3

PS. Ikke testet
Avatar billede AnyFellow Mester
21. november 2017 - 13:04 #14
Den sidste returnerer ingenting. Fjerner jeg GROUP BY finder den 1,2 og 4.

Jeg vil gerne have de userid'er, hvor ALLE 3 søgeordene findes. Om de findes i en eller flere poster er underordnet, bare alle 3 findes under userid'et. Jeg vil ikke have dem hvor f.eks. kun Tekst1 og Tekst2 findes.

Min sql i #6 gør dette korrekt, dog kan den ikke finde ud af hvis 2 af søgeordene findes i én post. Så bliver Count kun 2 i stedet for 3.
Avatar billede acore Ekspert
21. november 2017 - 13:54 #15
Tror jeg er med på opgaven - var bare lidt for hurtig:

SELECT t.uid FROM
(
SELECT DISTINCT 1 AS xyz,uid FROM tbl WHERE text like '%Tekst1%'
UNION
SELECT DISTINCT 2 AS xyz,uid FROM tbl WHERE text like '%Tekst2%'
UNION
SELECT DISTINCT 3 AS xyz,uid FROM tbl WHERE text like '%Tekst3%'
) AS t
GROUP BY t.uid
HAVING COUNT(*) = 3
Avatar billede AnyFellow Mester
21. november 2017 - 16:11 #16
Umiddelbart ser det fornuftigt ud. Jeg har ikke tid til at teste ordentlig i dag, men jeg tester grundigere i morgen og vender tilbage.
Avatar billede AnyFellow Mester
22. november 2017 - 13:54 #17
Har nu testet på kryds og tværs og med alverdens underlige kombinationer er søgeord, og har ikke fundet fejl.

Tak for hjælpen :)
Avatar billede acore Ekspert
22. november 2017 - 14:09 #18
Det var godt :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester