
acaul at rand
Jan 27, 2009, 2:07 PM
Post #12 of 17
(5113 views)
Permalink
|
On Jan 19, 2009, at 4:52 PM, David E. Wheeler wrote: > On Jan 19, 2009, at 1:00 PM, Ashlee Caul wrote: > >> Hi All. I am only a beginner Perl programmer, so I'm not very >> capable of working with Schwartzian transforms from my head. I am >> not even sure that the Schwartz is what I want. >> >> What I would really like to do is to select only stories that >> match certain criteria from fields defined by me, in this case an >> inventory_status. If a story (which represents a product) has an >> inventory_status of "Out of print" or "Removed from distribution" >> or "Outdated," I do not want it to be returned by $story->list() >> in the first place (if possible). Only "In stock" and "Coming >> soon" stories should be returned. > > Unfortunately, I think you have to limit these in Perl space, > rather than SQL. Though you could query on > > data_text => ANY('In stock', 'Coming soon') > > Which will work, as long as you don't have other fields that might > have those values. > >> Then, I want to sort these all by the document_year field, which >> is not a date but rather a text field because the year is all the >> information we have available for this field. Since this is >> neither the cover_date nor the publish_date, I cannot use those >> for the Order parameter in $story->list(); > > Correct. I do recommend you make it a date field, though, and set > its precision to year. Either way, though, yes, you will have to > sort them in the template code, and the Schwartzian transform is > the most efficient way to do so. > >> THEN (as if that were not enough), after the stories are sorted >> descending by document_year, I want to sort each year by >> doc_title, which is not the Bricolage title field, so I also >> cannot Order by that in $story->list(); > > Right. > >> Finally, the doc_titles include words such as "A," "An," and >> "The," and we do not wish to sort on those, so the template >> removes those words at the beginning of doc_title when sorting. > > Right, good. > >> Right now I am doing this with a complicated series of hashes and >> decision logic. This worked well for a while. Now, after four >> years, the lists that are being sorted are getting much longer. >> The story publish jobs keep failing because they exceed >> MAX_PROCESS_SIZE in bricolage.conf. We have already updated that >> value several times, and I am reluctant to continue doing so. >> >> Thank you for any assistance you can give. > > Switch to a schwartzian transform like so: > > my @sorted = > map { $_->[0] } > sort { $a->[1] <=> $b->[1] || $a->[2] cmp $b->[2] } > map { > (my $title = lc $_->get_value('doc_title') ) =~ s/^(?:an?| > the)\b//; > [ $_, $_->get_value('document_year'), $title ] > } Story->list( data_text => ANY('In stock', 'Coming soon') ); > OK, I took your map and shuffled it a little. This is now working. my @related_stories = map { $_->[0] } sort { $b->[1] <=> $a->[1] || $a->[2] cmp $b->[2] } map { (my $title = lc $_->get_value('doc_title') ) =~ s/^(A|An|The|Een|De| Het) (.+)/$2, $1/i; [ $_, $_->get_value('document_year'), $title ] } $story->list({ contrib_id => $author_id, element_key_name => "book", publish_status => 1 }); The inventory_status is a select box and turned out to be a blob, so I can't data_text it. Is there anything else I could add to the mapping so as to return only the books that have "In stock" or "Coming soon" as an inventory_status? (or specifically NOT to return books with "Removed from distribution" or "Outdated" as an inventory_status?) Thanks again. __________________________________________________________________________ This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.
|