2 Module : Gargantext.Database.Query.Table.NodeNgrams
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
10 NodeNgrams register Context of Ngrams (named Cgrams then)
14 {-# OPTIONS_GHC -fno-warn-orphans #-}
16 {-# LANGUAGE Arrows #-}
17 {-# LANGUAGE FlexibleContexts #-}
18 {-# LANGUAGE FlexibleInstances #-}
19 {-# LANGUAGE FunctionalDependencies #-}
20 {-# LANGUAGE QuasiQuotes #-}
21 {-# LANGUAGE MultiParamTypeClasses #-}
22 {-# LANGUAGE NoImplicitPrelude #-}
23 {-# LANGUAGE OverloadedStrings #-}
24 {-# LANGUAGE RankNTypes #-}
25 {-# LANGUAGE TemplateHaskell #-}
27 module Gargantext.Database.Query.Table.NodeNgrams
30 , module Gargantext.Database.Schema.NodeNgrams
34 import Data.List.Extra (nubOrd)
36 import Data.Maybe (Maybe, fromMaybe)
37 import Data.Text (Text)
38 import Database.PostgreSQL.Simple (FromRow)
39 import Database.PostgreSQL.Simple.FromRow (fromRow, field)
40 import Database.PostgreSQL.Simple.SqlQQ (sql)
41 import Database.PostgreSQL.Simple.ToField (toField)
42 import Database.PostgreSQL.Simple.Types (Values(..), QualifiedIdentifier(..))
43 import Gargantext.Core.Types
44 import Gargantext.Database.Prelude
45 import Gargantext.Database.Schema.Ngrams (NgramsType, ngramsTypeId, fromNgramsTypeId)
46 import Gargantext.Database.Schema.NodeNgrams
47 import Gargantext.Prelude
48 import qualified Data.List as List
49 import qualified Data.Map as Map
50 import qualified Database.PostgreSQL.Simple as PGS (Query, Only(..))
53 -- | Type for query return
54 data Returning = Returning { re_type :: !(Maybe NgramsType)
56 , re_ngrams_id :: !Int
60 instance FromRow Returning where
61 fromRow = Returning <$> (fromNgramsTypeId <$> field) <*> field <*> field
63 getCgramsId :: Map NgramsType (Map Text Int) -> NgramsType -> Text -> Maybe Int
64 getCgramsId mapId nt t = case Map.lookup nt mapId of
66 Just mapId' -> Map.lookup t mapId'
69 -- insertDb :: ListId -> Map NgramsType [NgramsElement] -> Cmd err [Result]
70 listInsertDb :: Show a => ListId
71 -> (ListId -> a -> [NodeNgramsW])
73 -- -> Cmd err [Returning]
74 -> Cmd err (Map NgramsType (Map Text Int))
75 listInsertDb l f ngs = Map.map Map.fromList
76 <$> Map.fromListWith (<>)
77 <$> List.map (\(Returning t tx id) -> (fromJust t, [(tx, id)]))
78 <$> List.filter (\(Returning t _ _) -> isJust t)
79 <$> insertNodeNgrams (f l ngs)
81 -- TODO optimize with size of ngrams
82 insertNodeNgrams :: [NodeNgramsW] -> Cmd err [Returning]
83 insertNodeNgrams nns = runPGSQuery query (PGS.Only $ Values fields nns')
85 fields = map (\t-> QualifiedIdentifier Nothing t) ["int4","int4","text","int4"
86 ,"int4","int4","int4","int4"
88 -- nns' :: [(Int, ListTypeId, NgramsText, NgramsTypeId ,NgramsField, NgramsTag, NgramsClass, Double)]
89 nns' = map (\(NodeNgrams _id (NodeId node_id'') node_subtype ngrams_terms ngrams_type ngrams_field ngrams_tag ngrams_class weight)
90 -> [ toField node_id''
91 , toField $ listTypeId node_subtype
92 , toField $ ngrams_terms
93 , toField $ ngramsTypeId ngrams_type
94 , toField $ fromMaybe 0 ngrams_field
95 , toField $ fromMaybe 0 ngrams_tag
96 , toField $ fromMaybe 0 ngrams_class
103 WITH input(node_id, node_subtype, ngrams_terms, ngrams_type, ngrams_field, ngrams_tag, ngrams_class, weight) AS (?),
104 return(id, ngrams_type, ngrams_id) AS (
105 INSERT INTO node_ngrams (node_id, node_subtype, ngrams_id, ngrams_type, ngrams_field, ngrams_tag, ngrams_class, weight)
106 SELECT i.node_id, i.node_subtype, ng.id, i.ngrams_type, i.ngrams_field, i.ngrams_tag, i.ngrams_class, i.weight FROM input as i
107 INNER JOIN ngrams as ng ON ng.terms = i.ngrams_terms
108 ON CONFLICT(node_id, node_subtype, ngrams_id) DO NOTHING
109 -- DO UPDATE SET node_subtype = excluded.node_subtype, ngrams_type = excluded.ngrams_type, ngrams_field = excluded.ngrams_field, ngrams_tag = excluded.ngrams_tag, ngrams_class = excluded.ngrams_class, weight = excluded.weight
110 RETURNING id, ngrams_type, ngrams_id
112 SELECT return.ngrams_type, ng.terms, return.id FROM return
113 INNER JOIN ngrams ng ON return.ngrams_id = ng.id;