On Mar 5, 8:23 am, mdipierro <[email protected]> wrote:
> Why not use a single request.vars.k with all keywords separated by a
> space and then
>
> query = reduce(lambda a,b:a|b,[db.sarua.keywords.like('%'+k
> +'%') for k in request.vars.k.split()])
Does this seem "dense" to you?...
If so, maybe this will make it readable:
First: all keywords separated by space works nicely (but you could
separate by whatever you want)...
for k in request.vars.k.split()
gets them out (so you could replace this by whatever mechanism you
choose)
Next: A DAL query is a set of queries separated by logical-OR (since
bit-OR is able to be overloaded, that symbol is used, but it's really
just logical-OR for DAL expressions). This gives rise to this part of
the shape:
query = a|b
Since you have an indeterminate amount of these, functools.reduce()
is handy: it will take a function (lambda in this case) and
sequentially return one result for each pair from a list, e.g.
reduce(add, [1,2,3]) === add(add(1,2),3). So this:
lambda a,b:a|b
returns the DAL expression "a|b" for each pair of arguments, (a,b).
Using list comprehension, we generate the query form as Johann
originally described it:
db.sarua.keywords.like(...)
Only one thing is left: Johann wanted a bit more complex expression
for applying each 'k':
(db.sarua.title.like(...) | db.sarua.keywords.like(...))
so you could have a co-routine produce that result, rather than hard-
coding this (which opens some flexible possibilities, but I'll leave
this as an exercise).
So, for now we have:
query = reduce( (some simple concatenation), (across all the
items in the request vars - however you want to get them) )
which might look like this:
query = reduce( (lambda a,b: a|b), [(db.sarua.title.like('%'+k
+'%')|db.sarua.keywords.like('%'+k+'%')) for k in
request.vars.k.split()])
If you're thinking "There has to be a better way" - I'm with
you... It would be nice if this were abstracted away, down in the
bowels of the DAL / ORM, but at the moment, it seems you have to deal
with it...
Perhaps you can think of how you would generally structure, write a
search for an arbitrary set of terms, over an arbitrary set of fields
(and tables).
- Yarko
>
> On Mar 5, 6:21 am, Johann Spies <[email protected]> wrote:
>
> > I have a form where the customer can type one keyword on each of the
> > five fields (the first field may not be empty). From these keywords I
> > have to build a query that would use .like('%' keyword'%') search in
> > at least two fields in the database.
>
> > I am trying something like this:
>
> > k1 = request.vars.k1
> > k2 = request.vars.k2
> > k3 = request.vars.k3
> > k4 = request.vars.k4
> > k5 = request.vars.k5
> > s = '%' + k1 + '%'
> > query = (db.sarua.title.like(s)|db.sarua.keywords.like(s))
>
> > The only way to do the rest looks to me something like this:
>
> > if k2:
> > ... building a longer query
> > if k3:
> > ... add to k2-query
>
> > Is there a better way? Maybe building a query to test a list of
> > strings separately against the different fields.
>
> > Johann
>
>
--
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/web2py?hl=en.