Rework searches to enable cross-table searches
It allows to search for multiple terms in multiple tables at once.
This commit is contained in:
parent
f9a5e5c5ff
commit
ce7e2c8a87
6 changed files with 75 additions and 47 deletions
|
@ -46,12 +46,16 @@ class Search < ActiveRecord::Base
|
||||||
|
|
||||||
search_term = self.class.connection.quote(to_tsquery)
|
search_term = self.class.connection.quote(to_tsquery)
|
||||||
|
|
||||||
|
dossier_ids = @gestionnaire.dossiers
|
||||||
|
.select(:id)
|
||||||
|
.where(archived: false)
|
||||||
|
.where.not(state: "draft")
|
||||||
|
|
||||||
q = self.class
|
q = self.class
|
||||||
.select("DISTINCT(searches.dossier_id)")
|
.select("DISTINCT(searches.dossier_id)")
|
||||||
.select("COALESCE(ts_rank(to_tsvector('french', searches.term::text), to_tsquery('french', #{search_term})), 0) AS rank")
|
.select("COALESCE(ts_rank(to_tsvector('french', searches.term::text), to_tsquery('french', #{search_term})), 0) AS rank")
|
||||||
.joins(:dossier)
|
.joins(:dossier)
|
||||||
.where(dossier_id: @gestionnaire.dossier_ids)
|
.where(dossier_id: dossier_ids)
|
||||||
.where("dossiers.archived = ? AND dossiers.state != ?", false, "draft")
|
|
||||||
.where("to_tsvector('french', searches.term::text) @@ to_tsquery('french', #{search_term})")
|
.where("to_tsvector('french', searches.term::text) @@ to_tsquery('french', #{search_term})")
|
||||||
.order("rank DESC")
|
.order("rank DESC")
|
||||||
.paginate(page: @page)
|
.paginate(page: @page)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
class UpdateSearchesToVersion2 < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
replace_view :searches, version: 2
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
replace_view :searches, version: 1
|
||||||
|
end
|
||||||
|
end
|
|
@ -982,40 +982,18 @@ CREATE TABLE users (
|
||||||
|
|
||||||
CREATE VIEW searches AS
|
CREATE VIEW searches AS
|
||||||
SELECT dossiers.id AS dossier_id,
|
SELECT dossiers.id AS dossier_id,
|
||||||
(((dossiers.id)::text || ' '::text) || (COALESCE(users.email, ''::character varying))::text) AS term
|
(((((((((((((((((((((((((((((((((((((((((((((((((((((((COALESCE(users.email, ''::character varying))::text || ' '::text) || (COALESCE(france_connect_informations.given_name, ''::character varying))::text) || ' '::text) || (COALESCE(france_connect_informations.family_name, ''::character varying))::text) || ' '::text) || (COALESCE(cerfas.content, ''::character varying))::text) || ' '::text) || (COALESCE(champs.value, ''::character varying))::text) || ' '::text) || (COALESCE(drop_down_lists.value, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.siren, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.numero_tva_intracommunautaire, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.forme_juridique, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.forme_juridique_code, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.nom_commercial, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.raison_sociale, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.siret_siege_social, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.nom, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.prenom, ''::character varying))::text) || ' '::text) || (COALESCE(rna_informations.association_id, ''::character varying))::text) || ' '::text) || (COALESCE(rna_informations.titre, ''::character varying))::text) || ' '::text) || COALESCE(rna_informations.objet, ''::text)) || ' '::text) || (COALESCE(etablissements.siret, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.naf, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.libelle_naf, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.adresse, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.code_postal, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.localite, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.code_insee_localite, ''::character varying))::text) || ' '::text) || (COALESCE(individuals.nom, ''::character varying))::text) || ' '::text) || (COALESCE(individuals.prenom, ''::character varying))::text) || ' '::text) || (COALESCE(pieces_justificatives.content, ''::character varying))::text) AS term
|
||||||
FROM (dossiers
|
FROM ((((((((((dossiers
|
||||||
JOIN users ON ((users.id = dossiers.user_id)))
|
JOIN users ON ((users.id = dossiers.user_id)))
|
||||||
UNION
|
LEFT JOIN france_connect_informations ON ((france_connect_informations.user_id = dossiers.user_id)))
|
||||||
SELECT cerfas.dossier_id,
|
LEFT JOIN cerfas ON ((cerfas.dossier_id = dossiers.id)))
|
||||||
COALESCE(cerfas.content, ''::character varying) AS term
|
LEFT JOIN champs ON ((champs.dossier_id = dossiers.id)))
|
||||||
FROM cerfas
|
LEFT JOIN drop_down_lists ON ((drop_down_lists.type_de_champ_id = champs.type_de_champ_id)))
|
||||||
UNION
|
LEFT JOIN entreprises ON ((entreprises.dossier_id = dossiers.id)))
|
||||||
SELECT champs.dossier_id,
|
|
||||||
(((COALESCE(champs.value, ''::character varying))::text || ' '::text) || (COALESCE(drop_down_lists.value, ''::character varying))::text) AS term
|
|
||||||
FROM (champs
|
|
||||||
JOIN drop_down_lists ON ((drop_down_lists.type_de_champ_id = champs.type_de_champ_id)))
|
|
||||||
UNION
|
|
||||||
SELECT entreprises.dossier_id,
|
|
||||||
(((((((((((((((((((((((COALESCE(entreprises.siren, ''::character varying))::text || ' '::text) || (COALESCE(entreprises.numero_tva_intracommunautaire, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.forme_juridique, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.forme_juridique_code, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.nom_commercial, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.raison_sociale, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.siret_siege_social, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.nom, ''::character varying))::text) || ' '::text) || (COALESCE(entreprises.prenom, ''::character varying))::text) || ' '::text) || (COALESCE(rna_informations.association_id, ''::character varying))::text) || ' '::text) || (COALESCE(rna_informations.titre, ''::character varying))::text) || ' '::text) || COALESCE(rna_informations.objet, ''::text)) AS term
|
|
||||||
FROM (entreprises
|
|
||||||
LEFT JOIN rna_informations ON ((rna_informations.entreprise_id = entreprises.id)))
|
LEFT JOIN rna_informations ON ((rna_informations.entreprise_id = entreprises.id)))
|
||||||
UNION
|
LEFT JOIN etablissements ON ((etablissements.dossier_id = dossiers.id)))
|
||||||
SELECT etablissements.dossier_id,
|
LEFT JOIN individuals ON ((individuals.dossier_id = dossiers.id)))
|
||||||
(((((((((((((COALESCE(etablissements.siret, ''::character varying))::text || ' '::text) || (COALESCE(etablissements.naf, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.libelle_naf, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.adresse, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.code_postal, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.localite, ''::character varying))::text) || ' '::text) || (COALESCE(etablissements.code_insee_localite, ''::character varying))::text) AS term
|
LEFT JOIN pieces_justificatives ON ((pieces_justificatives.dossier_id = dossiers.id)));
|
||||||
FROM etablissements
|
|
||||||
UNION
|
|
||||||
SELECT individuals.dossier_id,
|
|
||||||
(((COALESCE(individuals.nom, ''::character varying))::text || ' '::text) || (COALESCE(individuals.prenom, ''::character varying))::text) AS term
|
|
||||||
FROM individuals
|
|
||||||
UNION
|
|
||||||
SELECT pieces_justificatives.dossier_id,
|
|
||||||
COALESCE(pieces_justificatives.content, ''::character varying) AS term
|
|
||||||
FROM pieces_justificatives
|
|
||||||
UNION
|
|
||||||
SELECT dossiers.id AS dossier_id,
|
|
||||||
(((COALESCE(france_connect_informations.given_name, ''::character varying))::text || ' '::text) || (COALESCE(france_connect_informations.family_name, ''::character varying))::text) AS term
|
|
||||||
FROM (france_connect_informations
|
|
||||||
JOIN dossiers ON ((dossiers.user_id = france_connect_informations.user_id)));
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -2075,3 +2053,5 @@ INSERT INTO schema_migrations (version) VALUES ('20161011125345');
|
||||||
|
|
||||||
INSERT INTO schema_migrations (version) VALUES ('20161025150900');
|
INSERT INTO schema_migrations (version) VALUES ('20161025150900');
|
||||||
|
|
||||||
|
INSERT INTO schema_migrations (version) VALUES ('20161102154835');
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
-- this version allows to search for a single term within many tables,
|
||||||
|
-- but behaves badly with multiple terms scattered in multiple tables.
|
||||||
|
|
||||||
SELECT dossiers.id AS dossier_id,
|
SELECT dossiers.id AS dossier_id,
|
||||||
dossiers.id::text || ' ' ||
|
dossiers.id::text || ' ' ||
|
||||||
COALESCE(users.email, '') AS term
|
COALESCE(users.email, '') AS term
|
||||||
|
|
43
db/views/searches_v02.sql
Normal file
43
db/views/searches_v02.sql
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
-- this version merges all possible search terms together, complicating the
|
||||||
|
-- view, but enables searching for multiple terms from multiple tables at once.
|
||||||
|
|
||||||
|
SELECT dossiers.id AS dossier_id,
|
||||||
|
COALESCE(users.email, '') || ' ' ||
|
||||||
|
COALESCE(france_connect_informations.given_name, '') || ' ' ||
|
||||||
|
COALESCE(france_connect_informations.family_name, '') || ' ' ||
|
||||||
|
COALESCE(cerfas.content, '') || ' ' ||
|
||||||
|
COALESCE(champs.value, '') || ' ' ||
|
||||||
|
COALESCE(drop_down_lists.value, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.siren, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.numero_tva_intracommunautaire, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.forme_juridique, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.forme_juridique_code, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.nom_commercial, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.raison_sociale, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.siret_siege_social, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.nom, '') || ' ' ||
|
||||||
|
COALESCE(entreprises.prenom, '') || ' ' ||
|
||||||
|
COALESCE(rna_informations.association_id, '') || ' ' ||
|
||||||
|
COALESCE(rna_informations.titre, '') || ' ' ||
|
||||||
|
COALESCE(rna_informations.objet, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.siret, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.naf, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.libelle_naf, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.adresse, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.code_postal, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.localite, '') || ' ' ||
|
||||||
|
COALESCE(etablissements.code_insee_localite, '') || ' ' ||
|
||||||
|
COALESCE(individuals.nom, '') || ' ' ||
|
||||||
|
COALESCE(individuals.prenom, '') || ' ' ||
|
||||||
|
COALESCE(pieces_justificatives.content, '') AS term
|
||||||
|
FROM dossiers
|
||||||
|
INNER JOIN users ON users.id = dossiers.user_id
|
||||||
|
LEFT JOIN france_connect_informations ON france_connect_informations.user_id = dossiers.user_id
|
||||||
|
LEFT JOIN cerfas ON cerfas.dossier_id = dossiers.id
|
||||||
|
LEFT JOIN champs ON champs.dossier_id = dossiers.id
|
||||||
|
LEFT JOIN drop_down_lists ON drop_down_lists.type_de_champ_id = champs.type_de_champ_id
|
||||||
|
LEFT JOIN entreprises ON entreprises.dossier_id = dossiers.id
|
||||||
|
LEFT JOIN rna_informations ON rna_informations.entreprise_id = entreprises.id
|
||||||
|
LEFT JOIN etablissements ON etablissements.dossier_id = dossiers.id
|
||||||
|
LEFT JOIN individuals ON individuals.dossier_id = dossiers.id
|
||||||
|
LEFT JOIN pieces_justificatives ON pieces_justificatives.dossier_id = dossiers.id
|
|
@ -5,13 +5,8 @@ describe Search do
|
||||||
subject { liste_dossiers }
|
subject { liste_dossiers }
|
||||||
|
|
||||||
let(:liste_dossiers) do
|
let(:liste_dossiers) do
|
||||||
#described_class.refresh
|
|
||||||
described_class.new(gestionnaire: gestionnaire_1, query: terms).results
|
described_class.new(gestionnaire: gestionnaire_1, query: terms).results
|
||||||
end
|
end
|
||||||
#let(:dossier) do
|
|
||||||
# described_class.refresh
|
|
||||||
# described_class.search(gestionnaire: gestionnaire_1, query: terms)[1]
|
|
||||||
#end
|
|
||||||
|
|
||||||
let(:administrateur_1) { create(:administrateur) }
|
let(:administrateur_1) { create(:administrateur) }
|
||||||
let(:administrateur_2) { create(:administrateur) }
|
let(:administrateur_2) { create(:administrateur) }
|
||||||
|
@ -55,12 +50,6 @@ describe Search do
|
||||||
it { expect(subject.size).to eq(0) }
|
it { expect(subject.size).to eq(0) }
|
||||||
end
|
end
|
||||||
|
|
||||||
#describe 'search on ID dossier' do
|
|
||||||
# let(:terms) { "#{dossier_2.id}" }
|
|
||||||
|
|
||||||
# it { expect(dossier.id).to eq(dossier_2.id) }
|
|
||||||
#end
|
|
||||||
|
|
||||||
describe 'search on SIRET' do
|
describe 'search on SIRET' do
|
||||||
context 'when is part of SIRET' do
|
context 'when is part of SIRET' do
|
||||||
let(:terms) { '4181' }
|
let(:terms) { '4181' }
|
||||||
|
@ -82,9 +71,9 @@ describe Search do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'search on multiple fields' do
|
describe 'search on multiple fields' do
|
||||||
let(:terms) { 'octo test' }
|
let(:terms) { 'octo plop' }
|
||||||
|
|
||||||
pending { expect(subject.size).to eq(1) }
|
it { expect(subject.size).to eq(1) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue