on master help sign in
Added faculty search function
commite26a70989a44ed4aaab20eac688d2c9b8ae2031a authoriko <ilyakooo0@gmail.com> dateWed 8 May 2019, 21:56 (7 years ago) parenta01e757
4 files changed+75−5
denis/sql/indexes.sql+5 denis/src/Data/Faculty/Parser.hs+5−2 denis/src/Data/Query.hs+63−1 denis/src/Data/Schema.hs+2−2
denis/sql/indexes.sqlnew file+5
@@ -0,0 +1,5 @@
1+CREATE OR REPLACE FUNCTION my_array_to_text(text[])
2+ RETURNS text LANGUAGE sql IMMUTABLE AS $$SELECT array_to_string($1, ' ')$$;
3+
4+CREATE INDEX "faculty_text" ON "faculties" USING GIN (to_tsvector('russian', "facultyName" || ' ' || "facultyPath" || ' ' || "facultyCampusName" || ' ' || my_array_to_text("facultyTags")))
5+
denis/src/Data/Faculty/Parser.hs+5−2
@@ -43,7 +43,7 @@ getCampuses = do
4343 processCampus :: (HM.HashMap T.Text T.Text, T.Text) -> Maybe Campus
4444 processCampus (hm, name) = do
4545 code <- HM.lookup "hse-value" hm
46− return $ Campus name code
46+ return $ Campus (T.strip name) code
4747
4848
4949getFacultiesForCampus :: Campus -> Req [Faculty]
@@ -58,7 +58,10 @@ getFacultiesForCampus (Campus cName cCode) = do
5858 let els = elements [NodeElement el]
5959 nameTag <- listToMaybe . texts' mempty . map (NodeElement) . filter (classIs "link large b") $ els
6060 let name = T.strip . snd $ nameTag
61− url <- HM.lookup "href" . fst $ nameTag
61+ url <- (T.strip . snd . T.breakOnEnd "://") <$> (HM.lookup "href" . fst $ nameTag)
62+ _ <- if T.null url
63+ then Nothing
64+ else Just ()
6265 let tags = map (T.strip . snd) . texts' mempty . map (NodeElement) . filter (classIs "with-indent small tag-set") $ els
6366 let path = T.unwords . map (T.strip . snd) . texts' mempty . map (NodeElement) . filter (classIs "small") $ els
6467 return $ Faculty name url path cName cCode (V.fromList tags)
denis/src/Data/Query.hs+63−1
@@ -42,7 +42,8 @@ module Data.Query (
4242 leaveGroupChat,
4343 getGroupChatForUser,
4444 getFaculty,
45− updateFaculty
45+ updateFaculty,
46+ getFacultyFromQuery
4647) where
4748
4849import Squeal.PostgreSQL
@@ -69,6 +70,7 @@ import Servant.Docs
6970import Data.Proxy
7071import Data.Vector (Vector, toList, fromList)
7172import Data.Text (Text)
73+import qualified Data.Text as T
7274import Data.Channel.NamedChannel
7375import Data.Channel.AnonymousChannel
7476import Data.Maybe (fromMaybe)
@@ -78,6 +80,9 @@ import Data.Message
7880import Server.Query.Dialog
7981import qualified Server.Query.Pagination as P
8082import Data.Faculty
83+import Data.ByteString (ByteString)
84+import Data.Foldable (fold)
85+import Data.Char
8186
8287-- MARK: Documentation
8388
@@ -447,6 +452,56 @@ getGroupChatForUserQ = selectStar $
447452 where_ (#groupChatId .== param @2) &
448453 where_ (#groupChatUsers .? param @1)
449454
455+getFacultySearchResultQ :: Query Schema (TuplePG (Only Text)) (RowPG Faculty)
456+getFacultySearchResultQ = selectStar (from (table #faculties) &
457+ where_ (vector @@ query) &
458+ orderBy [tsRankCd vector query & Desc])
459+ where
460+ vector = tsVector "russian" (textArrayToText [
461+ #facultyName,
462+ #facultyPath,
463+ #facultyCampusName,
464+ (arrayToText #facultyTags)])
465+ query = tsQuery (param @1)
466+
467+tsRankCd
468+ :: Expression schema from grouping params ('NotNull 'PGtext)
469+ -> Expression schema from grouping params ('NotNull 'PGtext)
470+ -> Expression schema from grouping params ('NotNull 'PGfloat4)
471+tsRankCd vector query = UnsafeExpression $
472+ "ts_rank_cd" <> parenthesized (commaSeparated . map renderExpression $ [vector, query])
473+
474+tsVector
475+ :: ByteString -- ^ Language
476+ -> Expression schema from grouping params ('NotNull 'PGtext)
477+ -> Expression schema from grouping params ('NotNull 'PGtext)
478+tsVector lang x = UnsafeExpression $
479+ "to_tsvector" <> parenthesized (commaSeparated [singleQuotedUtf8 lang, renderExpression x])
480+
481+tsQuery
482+ :: Expression schema from grouping params ('NotNull 'PGtext)
483+ -> Expression schema from grouping params ('NotNull 'PGtext)
484+tsQuery = unsafeFunction "to_tsquery"
485+
486+arrayToText
487+ :: Expression schema from grouping params ('NotNull ('PGvararray ('NotNull 'PGtext)))
488+ -> Expression schema from grouping params ('NotNull 'PGtext)
489+arrayToText x = UnsafeExpression $
490+ "array_to_string" <> parenthesized (commaSeparated [renderExpression x, "' '"])
491+
492+(@@)
493+ :: Expression schema from grouping params (nullity0 'PGtext)
494+ -> Expression schema from grouping params (nullity1 'PGtext)
495+ -> Expression schema from grouping params (nullity2 'PGbool)
496+(@@) = unsafeBinaryOp "@@"
497+
498+space :: Expression schema from grouping params ('NotNull 'PGtext)
499+space = UnsafeExpression "' '"
500+
501+textArrayToText
502+ :: [Expression schema from grouping params ('NotNull 'PGtext)]
503+ -> Expression schema from grouping params ('NotNull 'PGtext)
504+textArrayToText = fold . L.intersperse space
450505
451506-- MARK: FrontEnd Data Structures
452507
@@ -694,8 +749,15 @@ getGroupChatForUser uId gId = do
694749 (Just c) -> return c
695750 Nothing -> lift $ S.throwError S.err404
696751
752+getFacultyFromQuery :: T.Text -> StaticPQ [Faculty]
753+getFacultyFromQuery query =
754+ runQueryParams getFacultySearchResultQ (Only . queryFromText $ query) >>= getRows
755+
697756-- MARK: Utils
698757
758+queryFromText :: Text -> Text
759+queryFromText = T.unwords . L.intersperse "&" . map (`T.append` ":*") . filter (not . T.null) . T.split (not . isAlphaNum)
760+
699761directionToOperator
700762 :: P.PaginationDirection
701763 -> (ConditionOp schema0 from0 grouping0 params0 nullity0 nullity1 (ty :: PGType),
denis/src/Data/Schema.hs+2−2
@@ -144,7 +144,7 @@ type Schema =
144144
145145 "faculties" ::: 'Table (
146146 '[
147− "pk_faculties" ::: 'PrimaryKey '["facultyName"]
147+ "pk_faculties" ::: 'PrimaryKey '["facultyURL"]
148148 ] :=>
149149 '[
150150 "facultyName" ::: 'NoDef :=> 'NotNull 'PGtext,
@@ -264,7 +264,7 @@ createTables = createTable #users (
264264 notNullable text `as` #facultyCampusCode :*
265265 notNullable (vararray text) `as` #facultyTags
266266 ) (
267− primaryKey #facultyName `as` #pk_faculties
267+ primaryKey #facultyURL `as` #pk_faculties
268268 )
269269-- quoteUniquenessCheck :: TableConstraintExpression Schema _ (Check '["rowElementOrd", "rowElementMarkdown", "rowElementLatex", "rowElementImage", "rowElementQuote", "rowElementAttachment"])
270270-- quoteUniquenessCheck = check (#rowElementOrd :* #rowElementMarkdown :* #rowElementLatex :* #rowElementImage :* #rowElementQuote :* #rowElementAttachment) $