2010-02-09 13 views
12

Questa potrebbe essere una domanda molto semplicistica, quindi ci scusiamo in anticipo, ma sono molto nuovo nell'utilizzo del database.Ricerca completa del testo di Postgres su più tabelle correlate

Mi piacerebbe avere Postgres eseguire la ricerca full-text su più tabelle unite. Immagina qualcosa come un utente modello, con i relativi modelli UserProfile e UserInfo. La ricerca sarebbe solo per gli utenti, ma includerebbe le informazioni da UserProfile e UserInfo.

Sto pianificando di utilizzare un indice gin per la ricerca. Non sono chiaro, tuttavia, se avrò bisogno di una colonna separata di tsvector nella tabella User per contenere i tsvector aggregati da tutte le tabelle e per impostare i trigger per mantenerlo aggiornato. O se è possibile creare un indice senza una colonna tsvector che si manterrà aggiornato ogni volta che uno qualsiasi dei campi rilevanti in una delle tabelle pertinenti cambia. Inoltre, qualsiasi suggerimento sulla sintassi del comando per creare tutto questo sarebbe molto apprezzato.

risposta

8

La tua migliore risposta è probabilmente quella di avere una colonna tsvector separata in ogni tabella (con un indice su, ovviamente). Se si aggregano i dati fino a un tsvector condiviso, questo creerà molti aggiornamenti su quello condiviso ogni volta che i singoli si aggiornano.

Avrete bisogno di un indice per tabella. Quindi, quando lo interroghi, ovviamente hai bisogno di più clausole WHERE, una per ogni campo. PostgreSQL calcolerà automaticamente quale combinazione di indici usare per ottenere i risultati più rapidi, probabilmente usando la scansione bitmap. Renderà le tue query un po 'più complesse da scrivere (poiché hai bisogno di più clausole di corrispondenza delle colonne), ma ciò mantiene la flessibilità di interrogare solo alcuni campi nei casi in cui vuoi.

Non è possibile creare un indice che traccia più tabelle. Per fare ciò è necessario disporre della colonna separata di tsvector e dei trigger su ogni tabella per aggiornarlo.

+2

Puoi entrare nei dettagli su come funziona la query di lettura? Sto cercando di trovare la documentazione sul modo migliore per fare la ricerca fullgrale postgresql su più tabelle e non trovo molto. Un problema a cui mi sono imbattuto è che se ho impostato un indice su ciascuna delle tabelle che stavo interrogando, postgresql non era in grado di utilizzare tutti gli indici quando ho fatto una query. Come: seleziona * dagli ordini lasciati partecipa agli utenti ... left join su line_items ... dove ts_vector ('english', orders.id) @@ ... o ts_vector ('english', users.name) @@. .. –

+1

Vedo anche che una ricerca in due tabelle esegue una scansione sequenziale ('SELECT COUNT (*) FROM products WHERE to_tsvector ('simple', products.name::text) @@ to_tsquery ('simple', 'foo ':: text); '), mentre una query che cerca una tabella esegue solo una scansione dell'indice bitmap utilizzando l'indice (' SELECT COUNT (*) FROM products LEFT JOIN brands ON products.brand_id = brands.id WHERE to_tsvector (' simple ' , products.name::text) @@ to_tsquery ('simple', 'foo' :: text) OR to_tsvector ('simple', brands.name::text) @@ to_tsquery ('simple', 'foo' :: testo); '). – wvengen

Problemi correlati