Permalink
Browse files

Serve only a subset of fields in search results (_fields annotation)

  • Loading branch information...
1 parent 0082d38 commit 75de273e4ee4e7620f5036f3c95964ce845d0c9c @dzhus committed Mar 22, 2012
Showing with 49 additions and 9 deletions.
  1. +11 −5 README.org
  2. +13 −0 README.org_archive
  3. +15 −4 src/Snap/Snaplet/Redson.hs
  4. +10 −0 src/Snap/Snaplet/Redson/Snapless/CRUD.hs
View
@@ -425,7 +425,14 @@
- _searchType=and or _searchType=or which indicates if all search
terms must match or just any of them.
- Response is currently list of JSON objects for matched instances.
+ - _fields=f1,f2,f3 which is a list of fields which must be
+ extracted from every matched instance and served in response.
+
+ Response is a list of JSON objects for matched instances. If
+ _fields is provided, then response is a list of arrays instead,
+ where every array contains values of specified fields in instance
+ (in order given by _fields parameter).
+
No per-field read permissions are checked.
** Extra features
*** Timeline
@@ -481,10 +488,9 @@
be changed without Redson restart anyways, and restart will be
required when new users are added as well).
-** TODO [#A] Faster search
- We should support serving of results as a table (array of arrays)
- to avoid redundant field names served with every matched instance.
- Client should be able to set fields to be served in output.
+** TODO External search providers
+ Might subscribe to model events via socket. Provides lists of
+ matching instance ids.
** MAYBE Update inverse references
When instance of model becomes referenced by another instance,
inverse reference should be updated by server.
View
@@ -62,3 +62,16 @@ Archived entries from file /home/sphinx/projects/snaplet-redson/README.org
separate group and served back to client transparently. This way
we'll be able to modify models and client without fiddling with
Metamodel.hs.
+
+* DONE [#A] Faster search
+ CLOSED: [2012-03-22 Чтв 20:54]
+ :PROPERTIES:
+ :ARCHIVE_TIME: 2012-03-22 Чтв 20:54
+ :ARCHIVE_FILE: ~/projects/snaplet-redson/README.org
+ :ARCHIVE_OLPATH: To do
+ :ARCHIVE_CATEGORY: README
+ :ARCHIVE_TODO: DONE
+ :END:
+ We should support serving of results as a table (array of arrays)
+ to avoid redundant field names served with every matched instance.
+ Client should be able to set fields to be served in output.
View
@@ -395,6 +395,7 @@ search =
fetchInstance id key = runRedisDB database $ do
Right r <- hgetall key
return $ (M.fromList $ ("id", id):r)
+ comma = 0x2c
in
ifTop $ withCheckSecurity $ \_ mdl -> do
case mdl of
@@ -407,6 +408,8 @@ search =
mType <- getParam "_matchType"
sType <- getParam "_searchType"
iLimit <- getParam "_limit"
+ outFields <- (\p -> maybe [] (B.split comma) p) <$>
+ getParam "_fields"
patFunction <- return $ case mType of
Just "p" -> prefixMatch
@@ -437,6 +440,7 @@ search =
Just (i, s))
(indices m)
+ -- For every term, get list of ids which match it
termIds <- runRedisDB database $
redisSearch m (catMaybes indexValues) patFunction
@@ -445,10 +449,17 @@ search =
[] -> writeLBS $ A.encode ([] :: [Value])
tids -> do
-- Finally, list of matched instances
- instances <- mapM (\id -> fetchInstance id $
- CRUD.instanceKey mname id)
- (searchType tids)
- writeLBS $ A.encode (take itemLimit instances)
+ instances <- take itemLimit <$>
+ mapM (\id -> fetchInstance id $
+ CRUD.instanceKey mname id)
+ (searchType tids)
+ -- If _fields provided, leave only requested
+ -- fields and serve array of arrays. Otherwise,
+ -- serve array of objects.
+ case outFields of
+ [] -> writeLBS $ A.encode instances
+ _ -> writeLBS $ A.encode $
+ map (flip CRUD.onlyFields outFields) instances
return ()
@@ -20,6 +20,7 @@ module Snap.Snaplet.Redson.Snapless.CRUD
, modelIndex
, modelTimeline
, collate
+ , onlyFields
)
where
@@ -134,6 +135,7 @@ deleteIndices mname id commit =
mapM_ (\(i, v) -> srem (modelIndex mname i v) [id])
commit
+
------------------------------------------------------------------------------
-- | Get old values of index fields stored under key.
getOldIndices :: B.ByteString -> [FieldName] -> Redis [Maybe B.ByteString]
@@ -143,6 +145,14 @@ getOldIndices key findices = do
Left _ -> []
Right l -> l
+
+------------------------------------------------------------------------------
+-- | Extract values of named fields from commit.
+onlyFields :: Commit -> [FieldName] -> [FieldValue]
+onlyFields commit fields =
+ catMaybes $ map (flip M.lookup commit) fields
+
+
------------------------------------------------------------------------------
-- | Create new instance in Redis and indices for it.
--

0 comments on commit 75de273

Please sign in to comment.