Rose Perrone
Rose Perrone

Reputation: 63586

mongodb via Haskell: How to enable text search

How can I write the following mongodb query in Haskell?

db.quotes.runCommand( "text", { search: "tomorrow",
                            filter: { speaker : "macbeth" } } )

This is the mongodb context, and this is the Haskell documentation.

UPDATE

I needed to run mongod with this command:

mongod --setParameter textSearchEnabled=true

and I also need to create indexes on the collections I want to search. I tried creating an index, but it didn't work. Here's my new question: mongodb via Haskell: creating a text-search index

The code below isn't relevant to my new question, but I'll keep it here because it's how I constructed the query.

              mDoc <- run pipe dbName $ runCommand
                ["text" =: (docTypeToText docType),
                  "search" =: (unwords keywords),
                    "filter" =: (selector $ selection query)]
              case mDoc of
                Left failure -> do putStrLn $ show failure
                                   return []
                Right doc -> let Array results = valueAt "results" doc
                                 ds = [d | Doc d <- results]
                             in return ds

Upvotes: 2

Views: 148

Answers (2)

Sergei Lebedev
Sergei Lebedev

Reputation: 2679

You need to use document form of the command, see for example findAndModify. Simplifying @ichistmeinname's answer:

{-# LANGUAGE OverloadedStrings #-}
search col term filter = runCommand [ "text"   =: col
                                    , "search" =: term
                                    , "filter" =: filter
                                    ]

Upvotes: 2

ichistmeinname
ichistmeinname

Reputation: 1500

I worked with MongoDB in a recent project and we used runCommand in connection with MongoDB's "text"-search mechanism. You just have to rebuild the JSON-structure with labels and corresponding values. In order to simplify the usage of Text-fields, the languages extension OverloadedStrings comes in handy.

A simple definition can be found here and the following code shows an example with "real" code.

{-# LANGUAGE OverloadedStrings #-}
createTextCommand aCollection aTextQuery aFilter =
  runCommand command
 where
 command :: Command
 command =
   let text     = [textLabel   =: aCollection]
       search   = [searchLabel =: aTextQuery]
       filter'  = [filterLabel =: aFilter]
   in text ++ search ++ filter'
 filterLabel :: Label
 filterLabel = "filter"
 searchLabel :: Label
 searchLabel = "search"
 textLabel :: Label
 textLabel = "text"

The only "tricky" part is the text-field, since there's no label in the MongoDB-version that you quoted, but when you digg deeper, you'll find a version with a corresponding text-label as I quoted in my other post.

Upvotes: 0

Related Questions