Add a sort_value field to contain the NFI-adjusted headings, and functions to search...
authorMike Rylander <mrylander@gmail.com>
Thu, 22 Sep 2011 20:19:10 +0000 (16:19 -0400)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Mon, 26 Sep 2011 00:39:57 +0000 (20:39 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/sql/Pg/011.schema.authority.sql
Open-ILS/src/sql/Pg/999.functions.global.sql

index 8dafc25..13955cf 100644 (file)
@@ -228,6 +228,7 @@ CREATE TABLE authority.simple_heading (
     record          BIGINT      NOT NULL REFERENCES authority.record_entry (id),
     atag            INT         NOT NULL REFERENCES authority.control_set_authority_field (id),
     value           TEXT        NOT NULL,
+    sort_value      TEXT        NOT NULL,
     index_vector    tsvector    NOT NULL
 );
 CREATE TRIGGER authority_simple_heading_fti_trigger
@@ -236,6 +237,7 @@ CREATE TRIGGER authority_simple_heading_fti_trigger
 
 CREATE INDEX authority_simple_heading_index_vector_idx ON authority.full_rec USING GIST (index_vector);
 CREATE INDEX authority_simple_heading_value_idx ON authority.simple_heading (value);
+CREATE INDEX authority_simple_heading_sort_value_idx ON authority.simple_heading (sort_value);
 
 CREATE OR REPLACE FUNCTION authority.simple_heading_set( marcxml TEXT ) RETURNS SETOF authority.simple_heading AS $func$
 DECLARE
@@ -246,6 +248,7 @@ DECLARE
     sf              TEXT;
     cset            INT;
     heading_text    TEXT;
+    sort_text       TEXT;
     tmp_text        TEXT;
     tmp_xml         TEXT;
     first_sf        BOOL;
@@ -271,10 +274,12 @@ BEGIN
             FOR sf IN SELECT * FROM regexp_split_to_table(acsaf.sf_list,'') LOOP
                 heading_text := heading_text || COALESCE( ' ' || oils_xpath_string('//*[@code="'||sf||'"]',tmp_xml::TEXT), '');
             END LOOP;
+
+            heading_text := public.naco_normalize(heading_text);
             
             IF nfi_used IS NOT NULL THEN
 
-                heading_text := SUBSTRING(
+                sort_text := SUBSTRING(
                     heading_text FROM
                     COALESCE(
                         NULLIF(
@@ -290,10 +295,13 @@ BEGIN
                     ) + 1
                 );
 
+            ELSE
+                sort_text := heading_text;
             END IF;
 
             IF heading_text IS NOT NULL AND heading_text <> '' THEN
-                res.value := public.naco_normalize( BTRIM(heading_text) );
+                res.value := heading_text;
+                res.sort_value := sort_text;
                 RETURN NEXT res;
             END IF;
 
@@ -320,6 +328,53 @@ index to defend against duplicated authority records from the same
 thesaurus.
 $$;
 
+CREATE OR REPLACE FUNCTION authority.find_start_pivot( a TEXT, q TEXT, lim INT DEFAULT 10, offs INT DEFAULT 0 ) RETURNS TABLE (rank NUMERIC, id BIGINT, record BIGINT, atag INT, value TEXT, sort_value TEXT) AS $$
+BEGIN
+    RETURN QUERY
+        SELECT  ts_rank_cd(ash.index_vector,ptsq.term,14)::numeric
+                    + CASE WHEN ash.sort_value LIKE t.term || '%' THEN 2 ELSE 0 END
+                    + CASE WHEN ash.value LIKE t.term || '%' THEN 1 ELSE 0 END,
+                ash.id,
+                ash.record,
+                ash.atag,
+                ash.value,
+                ash.sort_value
+          FROM  authority.simple_heading ash
+                JOIN authority.control_set_authority_field acsaf ON (acsaf.id = ash.atag)
+                JOIN authority.browse_axis_authority_field_map abaafm ON (abaafm.field = acsaf.id),
+                public.naco_normalize(q) t(term),
+                plainto_tsquery(q) ptsq(term)
+          WHERE abaafm.axis = a
+                AND ash.sort_value >= t.term OR ash.value >= t.term
+          ORDER BY ash.sort_value, 1 DESC
+          LIMIT lim
+          OFFSET offs;
+END;
+$$ LANGUAGE PLPGSQL ROWS 10;
+
+CREATE OR REPLACE FUNCTION authority.find_search_pivot( a TEXT, q TEXT, lim INT DEFAULT 10, offs INT DEFAULT 0 ) RETURNS TABLE (rank NUMERIC, id BIGINT, record BIGINT, atag INT, value TEXT, sort_value TEXT) AS $$
+BEGIN
+    RETURN QUERY
+        SELECT  ts_rank_cd(ash.index_vector,ptsq.term,14)::numeric
+                    + CASE WHEN ash.sort_value LIKE t.term || '%' THEN 2 ELSE 0 END
+                    + CASE WHEN ash.value LIKE t.term || '%' THEN 1 ELSE 0 END,
+                ash.id,
+                ash.record,
+                ash.atag,
+                ash.value,
+                ash.sort_value
+          FROM  authority.simple_heading ash
+                JOIN authority.control_set_authority_field acsaf ON (acsaf.id = ash.atag)
+                JOIN authority.browse_axis_authority_field_map abaafm ON (abaafm.field = acsaf.id),
+                public.naco_normalize(q) t(term),
+                plainto_tsquery(q) ptsq(term)
+          WHERE abaafm.axis = a
+                AND ash.index_vector @@ ptsq.term
+          ORDER BY 1 DESC, ash.sort_value
+          LIMIT lim
+          OFFSET offs;
+END;
+$$ LANGUAGE PLPGSQL ROWS 10;
 
 -- Adding indexes using oils_xpath_string() for the main entry tags described in
 -- authority.control_set_authority_field would speed this up, if we ever want to use it, though
index 3fedcf8..4d40304 100644 (file)
@@ -1439,8 +1439,8 @@ BEGIN
         DELETE FROM authority.simple_heading WHERE record = NEW.id;
     END IF;
 
-    INSERT INTO authority.simple_heading (record,atag,value)
-        SELECT record, atag, value FROM authority.simple_heading_set(NEW.marc);
+    INSERT INTO authority.simple_heading (record,atag,value,sort_value)
+        SELECT record, atag, value, sort_value FROM authority.simple_heading_set(NEW.marc);
 
     -- Flatten and insert the afr data
     PERFORM * FROM config.internal_flag WHERE name = 'ingest.disable_authority_full_rec' AND enabled;