Domanda

Ho un problema di sviluppo di un'app Web per il quale ho sviluppato una soluzione, ma sto cercando di trovare altre idee che potrebbero aggirare alcuni problemi di prestazioni che sto riscontrando.

dichiarazione problema:

  • un utente inserisce diverse parole chiave/token
  • l'applicazione cerca le corrispondenze con i token
  • è necessario un risultato per ogni token
    • cioè, se una voce ha 3 token, ho bisogno dell'ID della voce 3 volte
  • classificare i risultati
    • assegnare X punti per la corrispondenza dei token
    • ordinare gli ID delle voci in base ai punti
    • se i valori dei punti sono gli stessi, utilizza la data per ordinare i risultati

Quello che voglio poter fare, ma non ho capito, è inviare 1 query che restituisca qualcosa di simile ai risultati di un in(), ma restituisca un ID di voce duplicato per ogni token corrispondente per ogni ID di voce controllato.

Esiste un modo migliore per farlo rispetto a quello che sto facendo, utilizzando più query individuali che eseguono una query per token?Se sì, qual è il modo più semplice per implementarli?

modificare
Ho già tokenizzato le voci, quindi, ad esempio, "vedi spot run" ha un ID voce pari a 1 e tre token, "see", "spot", "run", e questi si trovano in una tabella di token separata, con ID di voce pertinenti per loro, quindi la tabella potrebbe assomigliare a questa:

'see', 1 
'spot', 1 
'run', 1 
'run', 2 
'spot', 3 
È stato utile?

Soluzione

potresti ottenerlo in una query utilizzando "UNION ALL" in MySQL.

Basta scorrere i token in PHP creando un UNION ALL per ciascun token:

ad esempio, se i token sono "x", "y" e "z" la tua query potrebbe assomigliare a questa

SELECT * FROM `entries` 
WHERE token like "%x%" union all 
    SELECT * FROM `entries` 
    WHERE token like "%y%" union all 
        SELECT * FROM `entries` 
        WHERE token like "%z%" ORDER BY score ect...

La clausola d'ordine dovrebbe operare sull'intero set di risultati come se fosse uno, che è ciò di cui hai bisogno.

In termini di prestazioni non sarà poi così veloce (immagino), tuttavia con i database il sovraccarico principale in termini di velocità è spesso l'invio della query al motore del database da PHP e la ricezione dei risultati.Con questa tecnica ciò accade solo una volta anziché una volta per token, quindi le prestazioni aumenteranno, ma non so se sarà sufficiente.

Altri suggerimenti

So che questa non è strettamente una risposta alla domanda che stai ponendo ma se la tua tabella è composta da migliaia anziché milioni di righe, allora una soluzione FULLTEXT potrebbe essere il modo migliore per andare qui.

In MySQL quando utilizzi MATCH sulla colonna indicizzata, a ciascuna parola chiave fornita verrà assegnato un punteggio di pertinenza (calcolato approssimativamente in base al numero di volte in cui ciascuna parola chiave è stata menzionata) che sarà più accurato del tuo metodo e sicuramente più efficace per più parole chiave.

Vedere qui:http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

Se stai utilizzando il modello UNION ALL potresti anche voler includere le seguenti parti nella tua query:

SELECT COUNT(*) AS C
...
GROUP BY ID
ORDER BY c DESC

Sebbene questo sia un esempio davvero banale, ti dà la frequenza delle corrispondenze per ciascun risultato e questo potrebbe essere uno pseudo-classifica con cui iniziare.

Probabilmente otterrai prestazioni molto migliori se utilizzi una struttura dati progettata per attività di ricerca anziché un database.Ad esempio, potresti provare a costruire un file indice invertito.Invece di scriverlo tu stesso, tuttavia, potresti anche voler esaminare qualcosa del genere Lucene che fa la maggior parte del lavoro per te.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top