2017-07-11 13 views
1

私はOpaleyeに変換しようとしているsqlクエリを持っています。Opaleyeでこのファジー検索SQLクエリを実装する方法は?

私の質問のポイント、すなわち、Opaleyeでファジー検索する方法に焦点を当てるようにコードを単純化します。

、私はそれが含むライセンス番号と任意の行を検索意味(いくつかの既存のOpaleye構造を持つ)Haskellは

namesTable :: O.Table NamesColumnWrite NamesColumnRead 
namesTable = O.Table "names" (pNames Names { id = O.optional "id" 
              , licenseNumber = O.required "license_number" 
              , fullName = O.required "full_name" 
              }) 

import qualified Database.PostgreSQL.Simple as PGS 

data Names' id' licenseNumber' fullName' = 
    Names 
     { id   :: id' 
     , licenseNumber  :: licenseNumber' 
     , fullName   :: fullName' 
     } deriving (Show, Eq) 

namesQuery :: Query NamesColumnRead 
namesQuery = queryTable NamesTable 

type NamesRead = Names' Int String String 
type NamesWrite = Names' (Maybe Int) String String 
type NamesColumnWrite = Names' (Maybe (O.Column O.PGInt4)) (O.Column O.PGText) (O.Column O.PGText) 
type NamesColumnRead = Names' (O.Column O.PGInt4) (O.Column O.PGText) (O.Column O.PGText) 

getNamesByFuzzyLicenseNumber :: PGS.Connection -> String -> IO [NamesRead] 
getNamesByFuzzyLicenseNumber conn licNumber = do 
    let query' = "SELECT id, license_number, full_name FROM get_names_by_fuzzy_license_number_fn(?)" 
    PGS.query conn query' [licNumber] 

であり、SQLは「あいまい検索」で

CREATE OR REPLACE FUNCTION get_names_by_license_number_fuzzy_fn(p_license_number VARCHAR) 
    RETURNS TABLE 
    (id INT 
    ,license_number VARCHAR 
    ,full_name TEXT 
    ) 
AS $$ 
    SELECT 
    id, 
    license_number, 
    full_name 
    FROM names 
    WHERE license_number LIKE '%' || p_license_number || '%' 
$$ 
LANGUAGE sql; 

です部分文字列として検索パラメータp_license_numberの値を返します。

このファジー検索クエリをOpaleyeに変換するにはどうすればよいですか?

これには、Sqlファイルを削除し、getNamesByLicenseNumberをHaskell Opaleyeクエリに置き換えることが含まれます。 は、私は答えではなく、厳密なマッチングのファジーを除い

getNamesByLicenseNumber :: String -> Query NamesColumnRead 
getNamesByLicenseNumber licNumber = proc() -> do 
    names <- namesQuery -<() 
    restrict -< pgString licNumber .== licenseNumber (names :: NamesColumnRead) 
    returnA -< names 

のようなものかもしれない期待しています。

答えて

0

あなたの質問が何であるかはわかりません私が改善する2つのことがあります。まず、関数の引数ではなく、文字列を引数としてQueryArrに渡します。次に.==ではなくlikeを使用してください。

getNamesByLicenseNumber :: QueryArr (Column PGText) NamesColumnRead 
getNamesByLicenseNumber = proc licNumber -> do 
    names <- namesQuery -<() 
    restrict -< licNumber `like` licenseNumber (names :: NamesColumnRead) 
    returnA -< names 

これは適切ですか?

関連する問題