pinecone-1.0.0: src/Pinecone/Search.hs
-- | Search
module Pinecone.Search
( -- * Main types
SearchWithVector(..)
, _SearchWithVector
, Matches(..)
, SearchWithText(..)
, _SearchWithText
, Hits(..)
-- * Other types
, Match(..)
, Query(..)
, _Query
, VectorQuery(..)
, Rerank(..)
, Hit(..)
, Usage(..)
-- * Servant
, API
) where
import Prelude hiding (filter)
import Pinecone.Embed (Input(..))
import Pinecone.Metadata (Filter, Scalar)
import Pinecone.Prelude
import Pinecone.Vectors (Namespace, SparseValues)
-- | Request body for @\/query@
data SearchWithVector = SearchWithVector
{ topK :: Natural
, namespace :: Maybe Namespace
, filter :: Maybe Filter
, includeValues :: Maybe Bool
, includeMetadata :: Maybe Bool
, vector :: Maybe (Vector Double)
, sparseVector :: Maybe SparseValues
, id :: Maybe Text
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Default `SearchWithVector`
_SearchWithVector :: SearchWithVector
_SearchWithVector = SearchWithVector
{ namespace = Nothing
, filter = Nothing
, includeValues = Nothing
, includeMetadata = Nothing
, vector = Nothing
, sparseVector = Nothing
, id = Nothing
}
-- | Response body for @\/query@
data Matches = Matches
{ matches :: Vector Match
, namespace :: Namespace
, usage :: Usage
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | A search request for records in a specific namespace.
data SearchWithText = SearchWithText
{ query :: Query
, fields :: Maybe (Vector Text)
, rerank :: Maybe Rerank
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Default `SearchWithText`
_SearchWithText :: SearchWithText
_SearchWithText = SearchWithText
{ fields = Nothing
, rerank = Nothing
}
-- | A successful search namespace response.
data Hits = Hits
{ usage :: Usage
, hits :: Vector Hit
} deriving stock (Eq, Generic, Show)
instance FromJSON Hits where
parseJSON value = do
Hits_{..} <- parseJSON value
let Result{..} = result
return Hits{..}
instance ToJSON Hits where
toJSON Hits{..} = toJSON Hits_{..}
where
result = Result{..}
data Hits_ = Hits_
{ result :: Result
, usage :: Usage
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Match for a vector
data Match = Match
{ id :: Text
, score :: Maybe Double
, values :: Maybe (Vector Double)
, sparseValues :: Maybe SparseValues
, metadata :: Maybe (Map Text Scalar)
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | The query inputs to search with
data Query = Query
{ top_k :: Natural
, filter :: Maybe Filter
, input :: Maybe Text
, vector :: Maybe VectorQuery
} deriving stock (Eq, Generic, Show)
data Query_ = Query_
{ top_k :: Natural
, filter :: Maybe Filter
, inputs :: Maybe Input
, vector :: Maybe VectorQuery
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
instance FromJSON Query where
parseJSON value = do
Query_{..} <- parseJSON value
let input = do
Input{..} <- inputs
return text
return Query{..}
instance ToJSON Query where
toJSON Query{..} = toJSON Query_{..}
where
inputs = do
text <- input
return Input{..}
-- | Default `Query`
_Query :: Query
_Query = Query
{ filter = Nothing
, input = Nothing
, vector = Nothing
}
-- | Vector query
data VectorQuery = VectorQuery
{ values :: Maybe (Vector Double)
, sparse_values :: Maybe (Vector Double)
, sparse_indices :: Maybe (Vector Natural)
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Parameters for reranking the initial search results
data Rerank = Rerank
{ model :: Text
, rank_fields :: Vector Text
, top_n :: Maybe Natural
, parameters :: Maybe (Map Text Value)
, query :: Maybe Text
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Search result
data Result = Result
{ hits :: Vector Hit
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Hit for the search document request
data Hit = Hit
{ _id :: Text
, _score :: Double
, fields :: Value
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Usage
data Usage = Usage
{ read_units :: Maybe Natural
, embed_total_tokens :: Maybe Natural
, rerank_units :: Maybe Natural
} deriving stock (Eq, Generic, Show)
deriving anyclass (FromJSON, ToJSON)
-- | Servant API
type API =
( "query"
:> ReqBody '[JSON] SearchWithVector
:> Post '[JSON] Matches
)
:<|> ( "records"
:> "namespaces"
:> Capture "namespace" Namespace
:> "search"
:> ReqBody '[JSON] SearchWithText
:> Post '[JSON] Hits
)