webForumDet fria alternativet

Strul med emission sökscript

11 svar · 464 visningar · startad av G8

G8Medlem sedan jan. 20011 213 inlägg
#1

Har lite problem att få AND, OR och AND NOT att funka som tänkt.

Verkar som om man inte behöver skriva in AND eller OR mellan orden, då den automatiskt söker på alla ord i söksträngen. På samma sätt ignorerar den AND NOT, vilket är den viktigaste funktionen tycker jag.

Följande kod ser ut exakt som i exemplet, vilket förbryllar mig en smula om det nu hade fungerat för andra...

Jag kör med MySQL, kanske är där skon klämmer...?

'skapa arrayer för AND, AND NOT och OR. 
'chr(0) gör det nu möjligt att matcha endast början på strängarna
mAndArr=filter(mQueryArr,chr(0) & "+",true)
mQueryArr=filter(mQueryArr,chr(0) & "+",false)
mNotArr=filter(mQueryArr,chr(0) & "-",true)
mQueryArr=filter(mQueryArr,chr(0) & "-",false)

'återskapa strängarna (ersätt chr(1) med mellanslag) och
'skapa WHERE-satser i arrayerna
for i=0 to ubound(mAndArr)
mAndArr(i)=replace(mAndArr(i),chr(1)," ")
mAndArr(i)=replace(mWhere,"%%","%" & mid(mAndArr(i),3) & "%")
next
for i=0 to ubound(mNotArr)
mNotArr(i)=replace(mNotArr(i),chr(1)," ")
mNotArr(i)=replace(mWhere,"%%","%" & mid(mNotArr(i),3) & "%")
next
for i=0 to ubound(mQueryArr)
mQueryArr(i)=replace(mQueryArr(i),chr(1)," ")
mQueryArr(i)=replace(mWhere,"%%","%" & mid(mQueryArr(i),2) & "%")
next

'tejpa ihop en färdig fråga
mQuery=join(mQueryArr," OR ")
if mQuery<>"" then 
mQuery="(" & mQuery & ")"
if ubound(mAndArr) > -1 then mQuery=mQuery & " AND "
end if
mQuery=mQuery & join(mAndArr," AND ")
if mQuery<>"" and ubound(mNotArr) > -1 then mQuery=mQuery & " AND NOT "
mQuery=mSQL & mQuery & join(mNotArr," AND NOT ")

http://www.webforum.nu/showthread.php?s=&forumid=22&threadid=8711

//G8

@ndersMedlem sedan juni 200032 969 inlägg
#2

Hur ser den färdiga SQL-frågan ut, och vad har du angett i sökningen?

G8Medlem sedan jan. 20011 213 inlägg
#3

Lite mera kod @nders:

Set Connection = Server.CreateObject("ADODB.Connection")
Connection.Open "clanglobe2"
dim i,j,mQuery,mQueryArr,mAndArr,mNotArr,mOrArr,mSQL,mWhere
alt = Request.Form("alt")
'grunddelarna i frågan beroende på valt alternativ
IF alt = "news" then
mSQL="SELECT nyheter.id, nyheter.rubrik, nyheter.artikel, nyheter.skribent, users.nick FROM nyheter INNER JOIN users ON nyheter.skribent = users.id WHERE " 
mWhere="(artikel LIKE '%%') OR (rubrik LIKE '%%') OR (skribent LIKE '%%') OR (users.nick LIKE '%%')"
Page="News"
elseif alt = "users" then
mSQL="SELECT users.id, klaner.namn AS klannamn, land.namn as landnamn, users.nick, users.city, users.info FROM users INNER JOIN klaner ON klaner.id = users.klanid INNER JOIN land ON users.country = land.id WHERE " 
mWhere="(users.nick LIKE '%%') OR (klaner.namn LIKE '%%') OR (users.info LIKE '%%') OR (land.namn LIKE '%%') OR (users.city LIKE '%%')"
Page="Users"
end if
'sökfältets värde
mQuery=request("search")
sokstrang=mquery
'loopa igenom allt och ersätt mellanslag inom citattecken med chr(1). 
'Denna bit går att göra med reguljära uttryck också
for i=1 to len(mQuery)
mAsc=asc(mid(mQuery,i,1))
if mAsc=34 then
mCount=mCount+1
blnInQ=not blnInQ
else
if blnInQ and mAsc=32 then
mQuery=left(mQuery,i-1) & chr(1) & mid(mQuery,i+1)
end if
end if

next

'om antalet citattecken är ojämnt ignoreras de helt
if mCount mod 2 <> 0 then
mQuery=replace(mQuery,chr(1)," ")
end if

'ta bort citattecknen
mQuery=replace(mQuery,chr(34),"")

'ersätt mellanslag med chr(0) och mellanslag
mQuery=chr(0) & replace(mQuery," "," " & chr(0))

'splitta upp i en array
mQueryArr=split(mQuery," ")

'skapa arrayer för AND, AND NOT och OR. 
'chr(0) gör det nu möjligt att matcha endast början på strängarna
mAndArr=filter(mQueryArr,chr(0) & "+",true)
mQueryArr=filter(mQueryArr,chr(0) & "+",false)
mNotArr=filter(mQueryArr,chr(0) & "-",true)
mQueryArr=filter(mQueryArr,chr(0) & "-",false)

'återskapa strängarna (ersätt chr(1) med mellanslag) och
'skapa WHERE-satser i arrayerna
for i=0 to ubound(mAndArr)
mAndArr(i)=replace(mAndArr(i),chr(1)," ")
mAndArr(i)=replace(mWhere,"%%","%" & mid(mAndArr(i),3) & "%")
next
for i=0 to ubound(mNotArr)
mNotArr(i)=replace(mNotArr(i),chr(1)," ")
mNotArr(i)=replace(mWhere,"%%","%" & mid(mNotArr(i),3) & "%")
next
for i=0 to ubound(mQueryArr)
mQueryArr(i)=replace(mQueryArr(i),chr(1)," ")
mQueryArr(i)=replace(mWhere,"%%","%" & mid(mQueryArr(i),2) & "%")
next

'tejpa ihop en färdig fråga
mQuery=join(mQueryArr," OR ")
if mQuery<>"" then 
mQuery="(" & mQuery & ")"
if ubound(mAndArr) > -1 then mQuery=mQuery & " AND "
end if
mQuery=mQuery & join(mAndArr," AND ")
if mQuery<>"" and ubound(mNotArr) > -1 then mQuery=mQuery & " AND NOT "
mQuery=mSQL & mQuery & join(mNotArr," AND NOT ")

if page = "News" then
mQuery=mQuery & " ORDER BY nyheter.rubrik asc limit 100"
else page = "Users" then
mQuery=mQuery & " ORDER BY users.nick asc limit 100"
end if
'frågan är klar! Ligger i mQuery

set rs=Connection.execute(mQuery)

Söker gör jag genom att skriva t.ex. Anders AND NOT Malmö. Jag har även testat att skriva Anders "AND NOT" Malmö,
funkar inte då heller. I vilket fall som helst, jag vill ju att man bara ska behöva skriva som i exempel ett,
alternativt byta ut and not mot ett minustecken och and mot ett plustecken... annars söka på alla ord..

Jag tror du fattar vad jag menar

Börjar bli lagom less på det här nu :l

//G8

@ndersMedlem sedan juni 200032 969 inlägg
#4

@nders skrev:

Hur ser den färdiga SQL-frågan ut

Ser man inte den resulterande SQL-frågan är det omöjligt att börja felsöka.

G8Medlem sedan jan. 20011 213 inlägg
#5

Visst fasiken, återkommer ikväll med mer info..

G8Medlem sedan jan. 20011 213 inlägg
#6

Söker jag efter nyheter, och skriver in

G8 AND NOT TEST

får jag följande resultat när jag skriver ut SQL-frågan, ser ju helt klart lite knasigt ut.. men hur lösa detta?

SELECT nyheter.id, nyheter.rubrik, nyheter.artikel, nyheter.skribent, users.nick FROM nyheter INNER JOIN users ON nyheter.skribent = users.id WHERE ((artikel LIKE '%G8%') OR (rubrik LIKE '%G8%') OR (skribent LIKE '%G8%') OR (users.nick LIKE '%G8%') OR (artikel LIKE '%AND%') OR (rubrik LIKE '%AND%') OR (skribent LIKE '%AND%') OR (users.nick LIKE '%AND%') OR (artikel LIKE '%NOT%') OR (rubrik LIKE '%NOT%') OR (skribent LIKE '%NOT%') OR (users.nick LIKE '%NOT%') OR (artikel LIKE '%TEST%') OR (rubrik LIKE '%TEST%') OR (skribent LIKE '%TEST%') OR (users.nick LIKE '%TEST%')) ORDER BY nyheter.rubrik asc limit 100

söker jag istället efter

G8 "AND NOT" TEST

alltså med fnuttar runt AND NOT ser SQL-frågan ut så här:

SELECT nyheter.id, nyheter.rubrik, nyheter.artikel, nyheter.skribent, users.nick FROM nyheter INNER JOIN users ON nyheter.skribent = users.id WHERE ((artikel LIKE '%G8%') OR (rubrik LIKE '%G8%') OR (skribent LIKE '%G8%') OR (users.nick LIKE '%G8%') OR (artikel LIKE '%AND NOT%') OR (rubrik LIKE '%AND NOT%') OR (skribent LIKE '%AND NOT%') OR (users.nick LIKE '%AND NOT%') OR (artikel LIKE '%TEST%') OR (rubrik LIKE '%TEST%') OR (skribent LIKE '%TEST%') OR (users.nick LIKE '%TEST%')) ORDER BY nyheter.rubrik asc limit 100

Ursäkta mig för mitt sena svar

//G8

G8Medlem sedan jan. 20011 213 inlägg
#7

Ingen som har en idé?

emissionMedlem sedan dec. 19996 721 inlägg
#8

Skriptet är nog rätt buggigt (har aldrig använt det själv...)

Det primära felet är dock att det inte är meningen att man ska kunna söka på

G8 AND NOT TEST

utan i stället på

G8 -TEST

G8Medlem sedan jan. 20011 213 inlägg
#9

Verkar funka bättre, men jag får fortfarande felaktiga resultat från databasen..

Söker efter

G8 -TEST

Resultat:

SELECT nyheter.id, nyheter.rubrik, nyheter.artikel, nyheter.skribent, users.nick FROM nyheter INNER JOIN users ON nyheter.skribent = users.id WHERE ((artikel LIKE '%G8%') OR (rubrik LIKE '%G8%') OR (skribent LIKE '%G8%') OR (users.nick LIKE '%G8%')) AND NOT (artikel LIKE '%TEST%') OR (rubrik LIKE '%TEST%') OR (skribent LIKE '%TEST%') OR (users.nick LIKE '%TEST%') ORDER BY nyheter.rubrik asc limit 100

Tycker det ser ut som om SQL-strängen ser OK ut, men jag får fortfarande sökresultat. ??

//G8

G8Medlem sedan jan. 20011 213 inlägg
#10

Hmm, tror jag lokaliserat problemet...

selectsatsen efter AND NOT eller AND måste ju också bindas in i en stor parantes, och detta måste göras för varje AND eller AND NOT, alltså:

SELECT nyheter.id, nyheter.rubrik, nyheter.artikel, nyheter.skribent, users.nick FROM nyheter INNER JOIN users ON nyheter.skribent = users.id WHERE ((artikel LIKE '%G8%') OR (rubrik LIKE '%G8%') OR (skribent LIKE '%G8%') OR (users.nick LIKE '%G8%')) AND NOT ((artikel LIKE '%TEST%') OR (rubrik LIKE '%TEST%') OR (skribent LIKE '%TEST%') OR (users.nick LIKE '%TEST%')) ORDER BY nyheter.rubrik asc limit 100

Nu är ju frågan dock, hur ska jag göra för att få in paranteserna runt de extra sökvillkoren?

Bör ju vara här nånstans som de ska in, men hur?

'tejpa ihop en färdig fråga
mQuery=join(mQueryArr," OR ")
if mQuery<>"" then 
mQuery="(" & mQuery & ")"
if ubound(mAndArr) > -1 then mQuery=mQuery & " AND "
end if
mQuery=mQuery & join(mAndArr," AND ")
if mQuery<>"" and ubound(mNotArr) > -1 then mQuery=mQuery & " AND NOT "
mQuery=mSQL & mQuery & join(mNotArr," AND NOT ")

//G8

G8Medlem sedan jan. 20011 213 inlägg
#11

Silly me..

Lösning på problemet...

'återskapa strängarna (ersätt chr(1) med mellanslag) och
'skapa WHERE-satser i arrayerna
for i=0 to ubound(mAndArr)
mAndArr(i)=replace(mAndArr(i),chr(1)," ")
mAndArr(i)=replace(mWhere,"%%","%" & mid(mAndArr(i),3) & "%")
next
for i=0 to ubound(mNotArr)
mNotArr(i)=replace(mNotArr(i),chr(1)," ")
mNotArr(i)=replace(mWhere,"%%","%" & mid(mNotArr(i),3) & "%")
next
for i=0 to ubound(mQueryArr)
mQueryArr(i)=replace(mQueryArr(i),chr(1)," ")
mQueryArr(i)=replace(mWhere,"%%","%" & mid(mQueryArr(i),2) & "%")
next
'tejpa ihop en färdig fråga
mQuery=join(mQueryArr," OR ")
if mQuery<>"" then 
[B]'##TA BORT
'mQuery="(" & mQuery & ")"[/B]
if ubound(mAndArr) > -1 then mQuery=mQuery & " AND "
end if
mQuery=mQuery & join(mAndArr," AND ")
if mQuery<>"" and ubound(mNotArr) > -1 then mQuery=mQuery & " AND NOT "
mQuery=mSQL & mQuery & join(mNotArr," AND NOT ")

Garvarde nästan ihjäl mig när jag såg det... fan va pantad (blind) man kan vara ibland.. :L

Tack för hjälpen allihopa

//G8

G8Medlem sedan jan. 20011 213 inlägg
#12

Glömde tillägga, släng in en extra parantes i mWhere ochså... Bara för att förtydliga

IF alt = "news" then
mSQL="SELECT nyheter.id, nyheter.rubrik, nyheter.artikel, nyheter.skribent, users.nick FROM nyheter INNER JOIN users ON nyheter.skribent = users.id WHERE " 
mWhere="((artikel LIKE '%%') OR (rubrik LIKE '%%') OR (skribent LIKE '%%') OR (users.nick LIKE '%%'))"
Page="News"
elseif alt = "users" then
mSQL="SELECT users.id, klaner.namn AS klannamn, land.namn as landnamn, users.nick, users.city, users.info FROM users INNER JOIN klaner ON klaner.id = users.klanid INNER JOIN land ON users.country = land.id WHERE " 
mWhere="((users.nick LIKE '%%') OR (klaner.namn LIKE '%%') OR (users.info LIKE '%%') OR (land.namn LIKE '%%') OR (users.city LIKE '%%'))"
Page="Users"
end if
257 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
123 ms — hämta statistik (db)
133 ms — hämta tråd, inlägg och bilagor (db)