[docker] update image, add README info
[gargantext.git] / src / Gargantext / Database / Facet.hs
index 8f5942d6645390d90bd698c586484b85e90e7aee..e642d21c340d31be2c4b0f508b4f68cff15a177b 100644 (file)
@@ -11,253 +11,304 @@ Portability : POSIX
 {-# OPTIONS_GHC -fno-warn-orphans        #-}
 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
 
-{-# LANGUAGE Arrows                      #-}
-{-# LANGUAGE DeriveGeneric               #-}
-{-# LANGUAGE TemplateHaskell             #-}
-{-# LANGUAGE FlexibleContexts            #-}
-{-# LANGUAGE FlexibleInstances           #-}
-{-# LANGUAGE MultiParamTypeClasses       #-}
-{-# LANGUAGE FunctionalDependencies      #-}
-{-# LANGUAGE NoMonomorphismRestriction   #-}
-
-module Gargantext.Database.Facet where
-
-import Prelude hiding (null, id, map, sum, not)
-
-import Gargantext.Types
-import Gargantext.Types.Node (NodeType)
-import Gargantext.Database.NodeNode
-import Gargantext.Database.NodeNodeNgram
-import Gargantext.Database.Node
-import Gargantext.Database.Queries
-import Gargantext.Utils.Prefix (unPrefix)
--- import Gargantext.Database.NodeNgram
-
--- import Data.Aeson (Value)
-import Data.Aeson.TH (deriveJSON)
+{-# LANGUAGE Arrows                    #-}
+{-# LANGUAGE DeriveGeneric             #-}
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE FunctionalDependencies    #-}
+{-# LANGUAGE MultiParamTypeClasses     #-}
+{-# LANGUAGE QuasiQuotes               #-}
+{-# LANGUAGE NoImplicitPrelude         #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE RankNTypes                #-}
+{-# LANGUAGE TemplateHaskell           #-}
+{-# LANGUAGE TypeFamilies              #-}
+------------------------------------------------------------------------
+module Gargantext.Database.Facet
+  ( runViewAuthorsDoc
+  , runViewDocuments
+  , filterWith
+
+  , Pair(..)
+  , Facet(..)
+  , FacetDoc
+  , FacetDocRead
+  , FacetPaired(..)
+  , FacetPairedRead
+  , OrderBy(..)
+  )
+  where
+------------------------------------------------------------------------
 import Control.Arrow (returnA)
-import Control.Lens.TH (makeLensesWith, abbreviatedFields)
+import Control.Lens ((^.))
+-- import Control.Lens.TH (makeLensesWith, abbreviatedFields)
+import Data.Aeson (FromJSON, ToJSON)
+import Data.Aeson.TH (deriveJSON)
+import Data.Either(Either(Left))
 import Data.Maybe (Maybe)
 import Data.Profunctor.Product.TH (makeAdaptorAndInstance)
+import Data.Swagger
+import Data.Text (Text)
 import Data.Time (UTCTime)
-import Database.PostgreSQL.Simple (Connection)
+import Data.Time.Segment (jour)
+import GHC.Generics (Generic)
+import Gargantext.Core.Types
+import Gargantext.Core.Utils.Prefix (unPrefix, unPrefixSwagger)
+import Gargantext.Database.Config (nodeTypeId)
+import Gargantext.Database.Schema.Node
+import Gargantext.Database.Schema.Ngrams
+import Gargantext.Database.Schema.NodeNode
+import Gargantext.Database.Schema.NodeNodeNgrams
+-- import Gargantext.Database.Schema.NodeNodeNgrams2
+import Gargantext.Database.Utils
+import Gargantext.Database.Queries.Filter
+import Gargantext.Database.Queries.Join (leftJoin5)
 import Opaleye
-import Opaleye.Internal.Join (NullMaker)
-
+import Prelude hiding (null, id, map, sum, not, read)
+import Servant.API
+import Test.QuickCheck (elements)
+import Test.QuickCheck.Arbitrary
 import qualified Opaleye.Internal.Unpackspec()
-import Data.Profunctor.Product.Default (Default)
 
-import Data.Time.Segment (jour)
+------------------------------------------------------------------------
+-- | DocFacet
 
-import Test.QuickCheck.Arbitrary
-import Test.QuickCheck (elements)
+-- data Facet = FacetDoc | FacetSources | FacetAuthors | FacetTerms
+--    deriving (Show, Generic)
+--instance FromJSON Facet
+--instance ToJSON   Facet
 
+type Favorite = Int
+type Title    = Text
 
+-- TODO remove Title
+type FacetDoc = Facet NodeId UTCTime Title HyperdataDocument (Maybe Favorite) (Maybe Double)
+-- type FacetSources = FacetDoc
+-- type FacetAuthors = FacetDoc
+-- type FacetTerms   = FacetDoc
 
-------------------------------------------------------------------------
--- | DocFacet
-type FacetDoc = Facet NodeId UTCTime HyperdataDocument Bool -- Double
 
-data Facet id created hyperdata favorite  = 
+data Facet id created title hyperdata favorite ngramCount = 
      FacetDoc { facetDoc_id         :: id
               , facetDoc_created    :: created
+              , facetDoc_title      :: title
               , facetDoc_hyperdata  :: hyperdata
               , facetDoc_favorite   :: favorite
-              } deriving (Show)
+              , facetDoc_ngramCount :: ngramCount
+              } deriving (Show, Generic)
+{- | TODO after demo
+data Facet id date hyperdata score = 
+     FacetDoc { facetDoc_id        :: id
+              , facetDoc_date      :: date
+              , facetDoc_hyperdata :: hyperdata
+              , facetDoc_score     :: score
+              } deriving (Show, Generic)
+-}
+
+data Pair i l = Pair {_p_id    :: i
+                     ,_p_label :: l
+  } deriving (Show, Generic)
+$(deriveJSON (unPrefix "_p_") ''Pair)
+$(makeAdaptorAndInstance "pPair" ''Pair)
+
+instance (ToSchema i, ToSchema l) => ToSchema (Pair i l) where
+  declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "_p_")
+instance (Arbitrary i, Arbitrary l) => Arbitrary (Pair i l) where
+  arbitrary = Pair <$> arbitrary <*> arbitrary
+
+data FacetPaired id date hyperdata score pair =
+  FacetPaired {_fp_id        :: id
+              ,_fp_date      :: date
+              ,_fp_hyperdata :: hyperdata
+              ,_fp_score     :: score
+              ,_fp_pair      :: pair
+  } deriving (Show, Generic)
+$(deriveJSON (unPrefix "_fp_") ''FacetPaired)
+$(makeAdaptorAndInstance "pFacetPaired" ''FacetPaired)
+
+instance ( ToSchema id
+         , ToSchema date
+         , ToSchema hyperdata
+         , ToSchema score
+         , ToSchema pair
+         ) => ToSchema (FacetPaired id date hyperdata score pair) where
+  declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "_fp_")
+
+instance ( Arbitrary id
+         , Arbitrary date
+         , Arbitrary hyperdata
+         , Arbitrary score
+         , Arbitrary pair
+         ) => Arbitrary (FacetPaired id date hyperdata score pair) where
+  arbitrary = FacetPaired <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+
+type FacetPairedRead = FacetPaired (Column PGInt4       )
+                                   (Column PGTimestamptz)
+                                   (Column PGJsonb      )
+                                   (Column PGInt4       )
+                                   ( Column (Nullable PGInt4)
+                                   , Column (Nullable PGText)
+                                   )
+
+-- | JSON instance
 $(deriveJSON (unPrefix "facetDoc_") ''Facet)
 
+-- | Documentation instance
+instance ToSchema FacetDoc where
+  declareNamedSchema = genericDeclareNamedSchema (unPrefixSwagger "facetDoc_")
+
+-- | Mock and Quickcheck instances
 instance Arbitrary FacetDoc where
-    arbitrary = elements [ FacetDoc id' (jour year 01 01) hp fav 
+    arbitrary = elements [ FacetDoc id' (jour year 01 01) t hp (Just cat) (Just ngramCount)
                          | id'  <- [1..10]
                          , year <- [1990..2000]
-                         , fav  <- [True, False]
-                         , hp   <- hyperdataDocuments
+                         , t    <- ["title", "another title"]
+                         , hp   <- arbitraryHyperdataDocuments
+                         , cat  <- [0..2]
+                         , ngramCount <- [3..100]
                          ]
 
 -- Facets / Views for the Front End
-type FacetDocRead  = Facet (Column PGInt4) (Column PGTimestamptz) (Column PGJsonb) (Column PGBool) -- (Column PGFloat8)
-
+-- | Database instances
 $(makeAdaptorAndInstance "pFacetDoc" ''Facet)
-$(makeLensesWith abbreviatedFields   ''Facet)
-
-------------------------------------------------------------------------
-type FacetDoc' = Facet' NodeId UTCTime HyperdataDocument Bool Int
-
-data Facet' id created hyperdata favorite ngramCount = 
-     FacetDoc' { facetDocP_id         :: id
-               , facetDocP_created    :: created
-               , facetDocP_hyperdata  :: hyperdata
-               , facetDocP_favorite   :: favorite
-               , facetDocP_ngramCount :: ngramCount
-               } deriving (Show)
-$(deriveJSON (unPrefix "facetDocP_") ''Facet')
-
-instance Arbitrary FacetDoc' where
-    arbitrary = elements [ FacetDoc' id' (jour year 01 01) hp fav ngramCount
-                         | id'  <- [1..10]
-                         , year <- [1990..2000]
-                         , hp   <- hyperdataDocuments
-                         , fav  <- [True, False]
-                         , ngramCount <- [1..10]
-                         ]
-
--- Facets / Views for the Front End
-type FacetDocRead'  = Facet' (Column PGInt4       )
-                             (Column PGTimestamptz)
-                             (Column PGJsonb      )
-                             (Column PGBool       )
-                             (Column PGInt4     )
-
-$(makeAdaptorAndInstance "pFacetDocP" ''Facet')
-$(makeLensesWith abbreviatedFields    ''Facet')
-
-------------------------------------------------------------------------
-
-
-getDocFacet :: Connection -> Int -> Maybe NodeType -> Maybe Offset -> Maybe Limit -> IO [FacetDoc]
-getDocFacet conn parentId nodeType maybeOffset maybeLimit = 
-    runQuery conn $ selectDocFacet parentId nodeType maybeOffset maybeLimit
-
-selectDocFacet :: ParentId -> Maybe NodeType -> Maybe Offset -> Maybe Limit -> Query FacetDocRead
-selectDocFacet parentId maybeNodeType maybeOffset maybeLimit =
-        limit' maybeLimit $ offset' maybeOffset $ orderBy (asc facetDoc_created) $ selectDocFacet' parentId maybeNodeType
-
-
--- | Left join to the favorites
-nodeNodeLeftJoin :: Query (NodeRead, NodeNodeReadNull)
-nodeNodeLeftJoin = leftJoin queryNodeTable queryNodeNodeTable (eqNode)
-    where
-        eqNode (Node n1 _ _ _ _ _ _, NodeNode _ n2 _) = ((.==) n1 n2)
-
-
-nodeNodeLeftJoin' :: (Column (Nullable PGInt4)) 
-                  -> Query (NodeRead, NodeNodeReadNull)
-nodeNodeLeftJoin' nId = leftJoin queryNodeTable queryNodeNodeTable (eqNode nId)
-        where
-            eqNode n (Node n1 _ _ _ _ _ _, NodeNode n1' n2 _) 
-                   = foldl (.&&) (pgBool True) [ ((.==) n1 n2)
-                                               , ((.==) n1' n)
-                                               ]
-
-nodeNodeLeftJoin'' :: Query (NodeRead, NodeRead, NodeNodeRead)
-nodeNodeLeftJoin'' = join3 queryNodeTable queryNodeTable queryNodeNodeTable eqNode
-        where
-            eqNode (Node n1 _ _ _ _ _ _, Node n2 _ _ _ _ _ _, NodeNode n1' n2' _) 
-                   = foldl (.&&) (pgBool True) [ ((.==) n2 n2')
-                                               , ((.==) (toNullable n1) n1')
-                                               ]
-
--- | Left join to the ngram count per document
-nodeNodeNgramLeftJoin :: Query (NodeRead, NodeNodeNgramReadNull)
-nodeNodeNgramLeftJoin = leftJoin queryNodeTable queryNodeNodeNgramTable (eqNode)
-     where
-        eqNode (Node n1 _ _ _ _ _ _, NodeNodeNgram n1' _ _ _) = ((.==) n1 n1')
-
-
-nodeNodeNgramLeftJoin' :: Column (Nullable PGInt4) 
-                       -> Query (NodeRead, NodeNodeNgramReadNull)
-nodeNodeNgramLeftJoin' nId = leftJoin queryNodeTable queryNodeNodeNgramTable (eqNode nId)
-     where
-        eqNode nId' (Node n1 _ _ _ _ _ _, NodeNodeNgram n1' n2 _ _) 
-                 = (.&&) ((.==) n1 n1')
-                         ((.==) nId' (toNullable n2))
-
-
-leftJoin3 :: (Default NullMaker (columnsL1, nullableColumnsR) nullableColumnsR1,
-              Default NullMaker columnsR nullableColumnsR,
-              Default Unpackspec columnsR columnsR,
-              Default Unpackspec nullableColumnsR nullableColumnsR,
-              Default Unpackspec columnsL1 columnsL1,
-              Default Unpackspec columnsL columnsL) =>
-              Query columnsL1 -> Query columnsR -> Query columnsL
-                -> ((columnsL1, columnsR) -> Column PGBool)
-                -> ((columnsL, (columnsL1, nullableColumnsR)) -> Column PGBool)
-                -> Query (columnsL, nullableColumnsR1)
-leftJoin3 q1 q2 q3 cond12 cond23 = leftJoin q3 (leftJoin q1 q2 cond12) cond23
-
-
-leftJoin3' :: Query (NodeRead, (NodeReadNull, NodeNodeNgramReadNull))
-leftJoin3' = leftJoin3 queryNodeTable  queryNodeNodeNgramTable queryNodeTable cond12 cond23
-    where
-         cond12 (Node occId _ _ _ _ _ _, NodeNodeNgram occId' _ _ _)
-                = (.==) occId occId'
-
-         cond23 :: (NodeRead, (NodeRead, NodeNodeNgramReadNull)) -> Column PGBool
-         cond23 (Node  docId _ _ _ _ _ _, (Node _ _ _ _ _ _ _, NodeNodeNgram _ docId' _ _))
-                = (.||) ((.==) (toNullable docId) docId') (isNull docId')
-
-
-leftJoin3''' :: Query (NodeRead, (NodeNodeReadNull, NodeReadNull))
-leftJoin3''' = leftJoin3 queryNodeNodeTable queryNodeTable queryNodeTable cond12 cond23
+-- $(makeLensesWith abbreviatedFields   ''Facet)
+
+type FacetDocRead = Facet (Column PGInt4       )
+                          (Column PGTimestamptz)
+                          (Column PGText       )
+                          (Column PGJsonb      )
+                          (Column (Nullable PGInt4)) -- Category
+                          (Column (Nullable PGFloat8)) -- Score
+
+-----------------------------------------------------------------------
+-----------------------------------------------------------------------
+data OrderBy =  DateAsc   | DateDesc
+             | TitleAsc   | TitleDesc
+             | ScoreDesc  | ScoreAsc
+             | SourceAsc  | SourceDesc
+             deriving (Generic, Enum, Bounded, Read, Show)
+
+instance FromHttpApiData OrderBy
+  where
+    parseUrlPiece "DateAsc"    = pure DateAsc
+    parseUrlPiece "DateDesc"   = pure DateDesc
+    parseUrlPiece "TitleAsc"   = pure TitleAsc
+    parseUrlPiece "TitleDesc"  = pure TitleDesc
+    parseUrlPiece "ScoreAsc"   = pure ScoreAsc
+    parseUrlPiece "ScoreDesc"  = pure ScoreDesc
+    parseUrlPiece "SourceAsc"  = pure SourceAsc
+    parseUrlPiece "SourceDesc" = pure SourceDesc
+    parseUrlPiece _            = Left "Unexpected value of OrderBy"
+
+instance ToParamSchema OrderBy
+instance FromJSON  OrderBy
+instance ToJSON    OrderBy
+instance ToSchema  OrderBy
+instance Arbitrary OrderBy
+  where
+    arbitrary = elements [minBound..maxBound]
+
+
+-- TODO-SECURITY check
+
+--{-
+runViewAuthorsDoc :: ContactId -> IsTrash -> Maybe Offset -> Maybe Limit -> Maybe OrderBy -> Cmd err [FacetDoc]
+runViewAuthorsDoc cId t o l order = runOpaQuery $ filterWith o l order $ viewAuthorsDoc cId t ntId
+  where
+    ntId = NodeDocument
+
+-- TODO add delete ?
+viewAuthorsDoc :: ContactId -> IsTrash -> NodeType -> Query FacetDocRead
+viewAuthorsDoc cId _ nt = proc () -> do
+  (doc,(_,(_,(_,contact)))) <- queryAuthorsDoc      -< ()
+
+  {-nn         <- queryNodeNodeTable -< ()
+  restrict -< nn_node1_id nn .== _node_id doc
+  -- restrict -< nn_delete   nn .== (pgBool t)
+  -}
+
+  restrict -< _node_id   contact   .== (toNullable $ pgNodeId cId)
+  restrict -< _node_typename doc   .== (pgInt4 $ nodeTypeId nt)
+
+  returnA  -< FacetDoc (_node_id        doc)
+                       (_node_date      doc)
+                       (_node_name      doc)
+                       (_node_hyperdata doc)
+                       (toNullable $ pgInt4 1)
+                       (toNullable $ pgDouble 1)
+
+queryAuthorsDoc :: Query (NodeRead, (NodeNodeNgramsReadNull, (NgramsReadNull, (NodeNodeNgramsReadNull, NodeReadNull))))
+queryAuthorsDoc = leftJoin5 queryNodeTable queryNodeNodeNgramsTable queryNgramsTable queryNodeNodeNgramsTable queryNodeTable cond12 cond23 cond34 cond45
     where
-         cond12 (NodeNode favId _ _, Node favId' _ _ _ _ _ _)
-                = (.||) ((.==) favId (toNullable favId')) (isNull $ toNullable favId)
-
-         cond23 :: (NodeRead, (NodeNodeRead, NodeReadNull)) -> Column PGBool
-         cond23 (Node  nId _ _ _ _ _ _, (NodeNode _ nId' _, Node _ _ _ _ _ _ _ ))
-                = ((.==) (nId) (nId'))
-
-
-getDocTest' :: Connection -> IO [FacetDoc']
-getDocTest' conn = runQuery conn selectDocFacet''
-
--- | Building the facet
--- selectDocFacet' :: ParentId -> Maybe NodeType -> Query FacetDocRead
-selectDocFacet'' :: Query FacetDocRead'
-selectDocFacet'' = proc () -> do
-        (n1,(nn,n2)) <- leftJoin3''' -< ()
-        restrict -< (.&&) (node_parentId n1 .== (toNullable $ pgInt4 347476))
-                          (node_typename n1 .== (pgInt4 4))
-
-        restrict -< (.||) (node_typename n2 .== (toNullable $ pgInt4 15))
-                          (isNull $ node_typename n2)
-        
-        restrict -< (.||) (node_parentId n2 .== (toNullable $ pgInt4 347476))
-                          (isNull $ node_parentId n2)
-
-        let isFav = ifThenElse (isNull $ nodeNode_score nn) (pgBool False) (pgBool True)
---        
-        returnA  -< FacetDoc' (node_id n1) (node_date n1) (node_hyperdata n1) (isFav) (pgInt4 1)
-
-
-
-
-
+         cond12 :: (NodeNodeNgramsRead, NodeRead) -> Column PGBool
+         cond12 (nodeNgram, doc) =  _node_id                  doc
+                                .== _nnng_node1_id nodeNgram
 
+         cond23 :: (NgramsRead, (NodeNodeNgramsRead, NodeReadNull)) -> Column PGBool
+         cond23 (ngrams, (nodeNgram, _)) =  ngrams^.ngrams_id
+                                        .== _nnng_ngrams_id nodeNgram
 
+         cond34 :: (NodeNodeNgramsRead, (NgramsRead, (NodeNodeNgramsReadNull, NodeReadNull))) -> Column PGBool
+         cond34 (nodeNgram2, (ngrams, (_,_)))= ngrams^.ngrams_id .== _nnng_ngrams_id       nodeNgram2
 
+         cond45 :: (NodeRead, (NodeNodeNgramsRead, (NgramsReadNull, (NodeNodeNgramsReadNull, NodeReadNull)))) -> Column PGBool
+         cond45 (contact, (nodeNgram2, (_, (_,_)))) = _node_id  contact    .== _nnng_node1_id         nodeNgram2
 
+--}
+------------------------------------------------------------------------
 
+-- TODO-SECURITY check
+runViewDocuments :: CorpusId -> IsTrash -> Maybe Offset -> Maybe Limit -> Maybe OrderBy -> Cmd err [FacetDoc]
+runViewDocuments cId t o l order =
+    runOpaQuery $ filterWith o l order $ viewDocuments cId t ntId
+  where
+    ntId = nodeTypeId NodeDocument
+
+viewDocuments :: CorpusId -> IsTrash -> NodeTypeId -> Query FacetDocRead
+viewDocuments cId t ntId = proc () -> do
+  n  <- queryNodeTable     -< ()
+  nn <- queryNodeNodeTable -< ()
+  restrict -< n^.node_id       .== nn^.nn_node2_id
+  restrict -< nn^.nn_node1_id  .== (pgNodeId cId)
+  restrict -< n^.node_typename .== (pgInt4 ntId)
+  restrict -< if t then nn^.nn_category .== (pgInt4 0)
+                   else nn^.nn_category .>= (pgInt4 1)
+  returnA  -< FacetDoc (_node_id        n)
+                       (_node_date      n)
+                       (_node_name      n)
+                       (_node_hyperdata n)
+                       (toNullable $ nn^.nn_category)
+                       (toNullable $ nn^.nn_score)
 
+------------------------------------------------------------------------
+filterWith :: (PGOrd date, PGOrd title, PGOrd score, hyperdata ~ Column SqlJsonb) =>
+     Maybe Gargantext.Core.Types.Offset
+     -> Maybe Gargantext.Core.Types.Limit
+     -> Maybe OrderBy
+     -> Select (Facet id (Column date) (Column title) hyperdata (Column score) ngramCount)
+     -> Select (Facet id (Column date) (Column title) hyperdata (Column score) ngramCount)
+filterWith o l order q = limit' l $ offset' o $ orderBy (orderWith order) q
 
 
+orderWith :: (PGOrd b1, PGOrd b2, PGOrd b3)
+          => Maybe OrderBy
+          -> Order (Facet id (Column b1) (Column b2) (Column SqlJsonb) (Column b3) score)
+orderWith (Just DateAsc)   = asc  facetDoc_created
+orderWith (Just DateDesc)  = desc facetDoc_created
 
+orderWith (Just TitleAsc)  = asc  facetDoc_title
+orderWith (Just TitleDesc) = desc facetDoc_title
 
-selectDocFacet' :: ParentId -> Maybe NodeType -> Query FacetDocRead
-selectDocFacet' parentId _ = proc () -> do
-    node <- (proc () -> do
+orderWith (Just ScoreAsc)  = asc  facetDoc_favorite
+orderWith (Just ScoreDesc) = desc facetDoc_favorite
 
-            -- Favorite Column
-            -- (Node docId docTypeId _ docParentId _ created docHyperdata, (Node _ favTypeId _ favParentId _ _ _, NodeNode _ docId' _))  <- leftJoin3'' -< ()
-            (Node docId docTypeId _ docParentId _ created docHyperdata, (NodeNode _ docId' _, (Node _ favTypeId _ favParentId _ _ _)))  <- leftJoin3''' -< ()
+orderWith (Just SourceAsc)  = asc  facetDoc_source
+orderWith (Just SourceDesc) = desc facetDoc_source
 
-            restrict -< docTypeId .== (pgInt4 15) .&& docParentId .== (toNullable $ pgInt4 parentId)
-            
-            -- select nn.score from nodes n left join nodes_nodes nn on n.id = nn.node2_id where n.typename =4;
-            -- Selecting the documents and joining Favorite Node
-            
-            restrict -< favParentId .== (toNullable $ pgInt4 parentId) .&& favTypeId .== (toNullable 4)
-            
-            -- let docTypeId'' = maybe 0 nodeTypeId (Just Document)
-            
-            -- Getting favorite data
-            let isFav = ifThenElse (isNull docId') (pgBool False) (pgBool True)
-            -- Ngram count by document
-            -- Counting the ngram
-            -- (Node occId occTypeId _ _ _ _ _, NodeNode _ _ _ count) <- nodeNodeNgramLeftJoin -< ()
-            -- restrict -< occId .== 347540
-            
-            --returnA  -< (FacetDoc n_id hyperdata isFav ngramCount)) -< ()
-            returnA  -< (FacetDoc docId created docHyperdata isFav)) -< ()
-    returnA -< node
+orderWith _                = asc facetDoc_created
 
+facetDoc_source :: PGIsJson a
+                => Facet id created title (Column a) favorite ngramCount
+                -> Column (Nullable PGText)
+facetDoc_source x = toNullable (facetDoc_hyperdata x) .->> pgString "source"