Sorting on 2 or more properties
Hi all, I am passing a list of objects to a zpt and would like to sort them on 2 or more of the properties. For example I have a class object with the following properties: id professor_name student_name course_number I would like to sort first on the professor_name, then course_number, and then finally student_name. I have googled and can only find examples for sorting on one property at a time. tia, Mike
On Friday 18 April 2003 03:51 pm, Michael Long wrote:
Hi all,
I am passing a list of objects to a zpt and would like to sort them on 2 or more of the properties. For example I have a class object with the following properties:
id professor_name student_name course_number
I would like to sort first on the professor_name, then course_number, and then finally student_name. I have googled and can only find examples for sorting on one property at a time.
You could write a general purpose sorting script as follows: ##Script (Python) "multiSort" ##parameters=objects, *sort_attrs ##title=Sort a list of objects by one or more of their attributes results = [] for object in objects: row = [getattr(object, attr) for attr in sort_attrs] row.append(object) results.append(tuple(row)) results.sort() return [row[-1] for row in results] hth, -Casey
Casey, thanks for the snippet of code. It solves the problem perfectly. -Mike On Mon, 2003-04-21 at 10:31, Casey Duncan wrote:
You could write a general purpose sorting script as follows:
##Script (Python) "multiSort" ##parameters=objects, *sort_attrs ##title=Sort a list of objects by one or more of their attributes
results = [] for object in objects: row = [getattr(object, attr) for attr in sort_attrs] row.append(object) results.append(tuple(row)) results.sort() return [row[-1] for row in results]
hth,
-Casey -- Michael Long <mlong@datalong.com>
Dear all, I have a very evasive problem again ;-) with ZCatalog. I'm very sorry if this topic has been dealt with; I couldn't find any info on this one. Here's a very simple concept I'd like to implement in my applications using ZCatalog: ** Every entry in the built-in ZCatalog should be unique. No duplicates!** However, every object's reference could get duplicated ( that is, inserted more than once ) when the object is accessed via acquisition. Say, when I have two folders, *dir1*, *dir2" and an object "obj1" in the dir1 folder: * Accessing obj1 via /dir1/obj1 catalogs it with the uid "/dir1/obj1". * Accessing it again via "/dir1/obj1", skips catalogging the object or recatalog it with the same uid. * Accessing it via "/dir2/obj1" or "/dir2/dir1/obj1" duplicates the catalog entry with with a different uid. It shouldn't be a serious problem when searching the catalog except for degraded, though negligible, performance due to too many duplicates, but it is indeed a serious problem when presenting found results: "/dir1/obj1", "/dir2/dir1/obj1", etc; they're different references pointing to the same object. ( I found the portal_catalog in one of my virtual hosts had tons of duplicates: more than 30,000 entries were removed when I recreated the catalog. ) I have a message board application with a built-in catalog and it recatalogs an article when a user views it by increasing its read count. ( Okay, it bloats the ZODB, but it's a whole lot different matter that should be addressed. Any hints or tips on this one would also be **greatly** appreciated! ) A list of articles is made from the board's built-in catalog on the fly. The read count is also an index: accessing an article via acquisition duplcates that very article's reference in the catalog over and over again. The problem aggravates when you use a virtual host monster. I solved this problem for my message board application by saving articles' relative paths as uids and reconstrucing their absolute paths based on the article container's (that is, the built-in catalog's) absolute_url() at the moment of retreiving them from the catalog. It works just fine even with VHM since the built-in catalog is never used **outside of the application.** But I couldn't figure out how to solve this with the portal_catalog tool, for example, or any other application that should be accessed site-wide. Although VHM is a great tool, it creates a lot of headaches in terms of paths and stuff for me. To address this problem, I put Squid as frontend before my ZEO clients (cache peers) and created a redirect script, which removes VHM paths: * http://www.example.net is redirected to /root/www_example_net, a VHM base * http://www.example.net/www_example_net is also valid, but leads to duplicate entries in the catalog * url redirector removes any reference of the folder www_example_net in the given url It only works for VHM cases, but is no good with accesses via acquisition. I want to make sure that no duplicates get into any catalog from the source code level even when using VHM or when users access objects by way of acquisition. ( The problem is easy to reproduce. In a CMF site, create a couple of folders and in one of them, create a news item and publish it. It'd appear on top of the news_slot box. Revisit the news item via acquisition, that is, putting the other folder on top of the item and edit it. Voila, the news_slot box shows two references for the news item. ) Creating a property in the catalog that holds unique keys for every object and checking the property before inserting a new entry....well...seems to be very kludgy. In short, can I catalog objects using acquisition-safe unique keys, say their oid's or auto-generated md5 hash or something? ( I wonder, if it's doable with little problem, why the designer of ZCatalog made it in such a way that object's physical paths work as uids, which may lead to the above-mentioned problems since they can't be unique when objects are acquired with different urls... please enlighten me if there's something I should be aware of in this regard, Casey. Terribly sorry for another newbish stupid question :-) Any hints or tips would be appreciated. Thanks in advance. Wankyu Choi --------------------------------------------------------------- Wankyu Choi CEO/President NeoQuest Communications, Inc. http://www.zoper.net http://www.neoboard.net ---------------------------------------------------------------
Wankyu Choi wrote: There are many people knowing the ZCatalog better than I do, but at least we can try to get the ball rolling ;).
Here's a very simple concept I'd like to implement in my applications using ZCatalog:
** Every entry in the built-in ZCatalog should be unique. No duplicates!**
The question here is unique with respect to what?
However, every object's reference could get duplicated ( that is, inserted more than once ) when the object is accessed via acquisition. Say, when I have two folders, *dir1*, *dir2" and an object "obj1" in the dir1 folder:
* Accessing obj1 via /dir1/obj1 catalogs it with the uid "/dir1/obj1".
* Accessing it again via "/dir1/obj1", skips catalogging the object or recatalog it with the same uid.
* Accessing it via "/dir2/obj1" or "/dir2/dir1/obj1" duplicates the catalog entry with with a different uid.
[Explanation snipped]
I want to make sure that no duplicates get into any catalog from the source code level even when using VHM or when users access objects by way of acquisition.
( The problem is easy to reproduce. In a CMF site, create a couple of folders and in one of them, create a news item and publish it. It'd appear on top of the news_slot box. Revisit the news item via acquisition, that is, putting the other folder on top of the item and edit it. Voila, the news_slot box shows two references for the news item. )
[snip]
In short, can I catalog objects using acquisition-safe unique keys, say their oid's or auto-generated md5 hash or something?
I can't follow you here, because above you said that that you want to implement that "Accessing it via "/dir2/obj1" or "/dir2/dir1/obj1" duplicates the catalog entry with with a different uid." This isn't acquisition safe.
( I wonder, if it's doable with little problem, why the designer of ZCatalog made it in such a way that object's physical paths work as uids, which may lead to the above-mentioned problems since they can't be unique when objects are acquired with different urls... please enlighten me if there's something I should be aware of in this regard, Casey. Terribly sorry for another newbish stupid question :-)
Here is where there seems to be a misunderstanding, at least as far *I* understand the ZCatalog: It's up to the object to pass an uid to the Catalog if he/she wants, and the decision what to use for the uid is up to the programmer who implements that (i.e. it's not a (Z)Catalog implementation problem). All cases that I have seen in stock zope/CMF are using getPhysicalPath() for that, and this is also the default if no uid is passed. Therefore I can't see how your example with the news item could happen. CMFCatalogAware shouldn't do this, and I couldn't reproduce this with a custom type of mine, which uses CMFCatalogAware like NewsItems do AFAIK. Additionally getPhysicalPath() is also the answer to your acquisition-safe unique key, because it accomplishs exactly that, acquisition safe and zope-wide uniqueness. It also doesn't take vhms or the hostname into account, so I really can't see what happens there. Another question, when you say you do _index_ your read count, do you mean storing it as meta_data in the catalog? cheers, oliver
Hi,
There are many people knowing the ZCatalog better than I do, but at least we can try to get the ball rolling ;).
That's great. And thanks.
** Every entry in the built-in ZCatalog should be unique. No duplicates!**
The question here is unique with respect to what?
Being unique in every aspect...site-wde uniqueness, etc. I didn't think that'd be ambigous ;-)
In short, can I catalog objects using acquisition-safe unique keys, say their oid's or auto-generated md5 hash or something?
I can't follow you here, because above you said that that you want to implement that "Accessing it via "/dir2/obj1" or "/dir2/dir1/obj1" duplicates the catalog entry with with a different uid."
This isn't acquisition safe.
I must have been really ambiguous in making myself understood. This is exactly what I **don't** need, and it's why objects being catalogged are **not** acquisition-safe. I just tried to demonstrate **what shouldn't be happening**. <snip snip>
Here is where there seems to be a misunderstanding, at least as far *I* understand the ZCatalog:
I do think so ;-)
It's up to the object to pass an uid to the Catalog if he/she wants, and the decision what to use for the uid is up to the programmer who implements that (i.e. it's not a (Z)Catalog implementation problem). All cases that I have seen in stock zope/CMF are using getPhysicalPath() for that, and this is also the default if no uid is passed. Therefore I can't see how your example with the news item could happen. CMFCatalogAware shouldn't do this, and I couldn't reproduce this with a custom type of mine, which uses CMFCatalogAware like NewsItems do AFAIK. Additionally getPhysicalPath() is also the answer to your acquisition-safe unique key, because it accomplishs exactly that, acquisition safe and zope-wide uniqueness. It also doesn't take vhms or the hostname into account, so I really can't see what happens there.
That's weird. ( Just take a step back and see things as if they were when your were also a newbie to Zope and stuff ;-) I tried a unique key myself, but didn't work with the getPath() or getURL() methods of the brain objects a search operations returns. And that very getPhysicalPath() call returns a different url when you access an object via acquisition in my case: CMF 1.3.1. That's why I came under the impression that the getPhyicalPath() doesn't return a unique path with VHM or when an object is accessed via acquisition. As per VHM, I have the following setup, for example: /root/Zoper - translates into www.zoper.net When you create an object in http://www.zoper.net, you get a catalog entry, say "a_news_item" with a uid "/Zoper/a_news_item". If you edit this item via http://www.zoper.net/Zoper, you get a duplicate with the uid "/Zoper/Zoper/a_news_item". Here goes even funnier situation: when you visit this item and edit it via "http://www.zoper.net/Zoper/Zoper/Zoper", you'd get a catalog entry, "/Zoper/Zoper/Zoper/Zoper/a_news_item". This is what's happening with my CMF site's portal catalog: CMF 1.3.1 with Plone 1.0.1 ( Zope 2.6.1 ) I haven't done anything myself to this catalog.
Another question, when you say you do _index_ your read count, do you mean storing it as meta_data in the catalog?
No. There's a method called getNeoPortalContentReadCount() common to all the objects my applications create that does the job when indexing an object, not a metadata entry.
cheers, oliver
I appreciate your feedback^^ It's so hard to get any replires to my dumb questions these days...sigh :) Best regards, Wankuyu Choi --------------------------------------------------------------- Wankyu Choi CEO/President NeoQuest Communications, Inc. http://www.zoper.net http://www.neoboard.net ---------------------------------------------------------------
Wankyu Choi wrote at 2003-4-22 18:51 +0900:
I have a very evasive problem again ;-) with ZCatalog. I'm very sorry if this topic has been dealt with; I couldn't find any info on this one.
Here's a very simple concept I'd like to implement in my applications using ZCatalog:
** Every entry in the built-in ZCatalog should be unique. No duplicates!**
However, every object's reference could get duplicated ( that is, inserted more than once ) when the object is accessed via acquisition. Say, when I have two folders, *dir1*, *dir2" and an object "obj1" in the dir1 folder:
* Accessing obj1 via /dir1/obj1 catalogs it with the uid "/dir1/obj1".
* Accessing it again via "/dir1/obj1", skips catalogging the object or recatalog it with the same uid.
* Accessing it via "/dir2/obj1" or "/dir2/dir1/obj1" duplicates the catalog entry with with a different uid.
Modern Zope releases uses "getPhysicalPath" as "uid" for the catalog. "getPhysicalPath" is independant from the access path (up to hacks). When you see the same object catalogued under different catalog uids, you should either upgrade to Zope 2.6.1 or fix the code that does not use "getPhysicalPath". A likely candidate it "Products.ZCatalog.CatalogAware". Replace this by "Products.ZCatalog.CatalogPathAware". Dieter
When you see the same object catalogued under different catalog uids, you should either upgrade to Zope 2.6.1 or fix the code that does not use "getPhysicalPath". A likely candidate it >"Products.ZCatalog.CatalogAware". Replace this by "Products.ZCatalog.CatalogPathAware".
I already use Zope 2.6.1. Hm.. CMFCore's PortalContent imports Products.ZCatalog.CatalogAware, not CatalogPathAware. Probably, this is the source of my problem, then? ( CMF 1.3.1, the latest. ) May I ask why CMF imports CatalogAware instead of CatalogPathAware? CMF people should know better than that. I just want to know if there's any particular reason why, since I'm basing my own applications on CMF. Thanks in advance. --------------------------------------------------------------- Wankyu Choi CEO/President NeoQuest Communications, Inc. http://www.zoper.net http://www.neoboard.net ---------------------------------------------------------------
Wankyu Choi wrote:
When you see the same object catalogued under different catalog uids, you
should either upgrade to Zope 2.6.1 or fix the code that does not use "getPhysicalPath". A likely candidate it >"Products.ZCatalog.CatalogAware". Replace this by "Products.ZCatalog.CatalogPathAware".
I already use Zope 2.6.1.
Hm.. CMFCore's PortalContent imports Products.ZCatalog.CatalogAware, not CatalogPathAware. Probably, this is the source of my problem, then? ( CMF 1.3.1, the latest. )
May I ask why CMF imports CatalogAware instead of CatalogPathAware? CMF people should know better than that. I just want to know if there's any particular reason why, since I'm basing my own applications on CMF.
Sorry for asking that, but are you really sure that you are using CMF 1.3.1? With my copy, it imports CMFCatalogAware, and CMFCatalogAware calls the portal_catalog's index_object() method, which is as follows: def __url(self, ob): return join(ob.getPhysicalPath(), '/') ... def indexObject(self, object): '''Add to catalog. ''' url = self.__url(object) self.catalog_object(object, url) This is why I wondered about your example with the news item (or whatever it is called). cheers, oliver
participants (5)
-
Casey Duncan -
Dieter Maurer -
Michael Long -
Oliver Bleutgen -
Wankyu Choi