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.

Reply via email to