内容的查询和分类
- 英文原文
- Searching and Categorizing Content
- 翻译来源
- zope.slat.org
- 翻译作者
- 由 marr 先行完成部份內容中譯
- 整理
- 潘俊勇 转换为简体
第九章:文件搜寻与编目
catalog 是 Zope 内建的搜寻引擎,它能协助你针对各式各样 Zope 物件进行编目与搜寻的工作。你也可以利用它来搜寻外部资料,例如关连式资料库、档案、远端网页等。除了搜寻功能之外,你可以使用 catalog 来为一群物件进行分类整理。
catalog 本身支援多种查询介面,你可以执行全文检索的功能,也可以一次针对多个索引进行搜寻,除此之外,对于完成索引的物件,catalog 可以针对其 metadata 进行追踪。下列是两个最常见的 ZCatalog? 使用方式:
群组编目方式 (Mass Cataloging)
一次针对一大群物件进行编目动作。
自动编目方式 (Automatic Cataloging)
物件产生时进行编目,并追踪记录其改变历程。
群组编目方式的使用介绍
让我们先了解利用 catalog 搜寻文件的方法。一次针对一群物件,同时进行编目的动作,称为「群组编目方式」,其包括下列三个步骤:
- 建立一个 ZCatalog?。
- 选取物件并对它们进行编目。
- 建立一个网页介面来对 catalog 进行搜寻。
请从物件新增选单中选择 ZCatalog? 物件,随后的画面是 ZCatalog? 新增表单,如图 9-1 所示。
图 9-1: ZCatalog? 之新增表单
新增表单的画面上,要求输入一个「识别」(Id) 及「标题」(Title),另一个表单项目则是称为「词汇」(Vocabulary) 的下拉选单。截至目前为止,直接将选项设定为「为我新增」(Create one for me) 即可。在 ZCatalog? 识别栏填写 "AnimalTracker?",并点击「新增」(Add) 按钮,以建立一个新的 catalog。catalog 的代表图示,外观与 folder 相似,上头多了个放大镜的图样。点选 AnimalTracker?的图示,以进入 catalog 的内容管理介面 (Contents view)。
ZCatalog? 的管理介面看起来和 folder 物件很像,但它多了一些额外的设定项目,和标准的 folder 物件相比,ZCatalog 计有六个完全相同的设定项目。ZCatalog 全部的介面项目如下:
「内容」(Contents)、
「编目」(Catalog)、
「属性」(Properties)、
「索引」(Indexes)、
「诠释资料」(MetaData?)、
「搜寻物件」(Find Objects)、
「进阶」(Advanced)、
「复原」(Undo)、
「安全设定」(Security)、
「拥有权」(Ownership)。
当你点选一个 ZCatalog? 后,会显示「内容」介面,接着你可以建立新的物件,把它们整理在 ZCatalog? 里,就跟 folder 的管理方式一样。不过,值得注意的是,物件整理在 catalog 里,并不代表该物件就是可搜寻的。
现在你已成功建立一个 ZCatalog?,接下来的步骤,就是寻找物件并将它们进行编目动作。假设你建立了一个动物园网站 (ZopeZoo?),提供有关动物的介绍,为了配合接续的例子,请建立两个包含 reptile 与 amphibian 介绍资料的 DTML Document 物件:
- Title: Chilean four-eyed frog
The Chilean four-eyed frog has a bright pair of spots on its rump that look like enormous eyes. When seated, the frog's thighs conceal these eyespots. When predators approach, the frog lowers its head and lifts its rump, creating a much larger and more intimidating head. Frogs are amphibians.
- Title: Carpet Python
Morelia spilotes variegata averages 2.4 meters in length. It is a medium-sized python with black-to-gray patterns of blotches, crossbands, stripes, or a combination of these markings on a light yellowish-to-dark brown background. Snakes are reptiles.
动物园网站的访客,会希望能够搜寻园内动物的资讯,例如说,两栖爬虫专家们想要知道你的网站里是否有他们喜爱的蛇类,你应该提供几个关键字词的搜寻功能,并且能够显示含有这些关键字词的所有文件资料。搜寻服务正是网路上最有用,也是最常见的网站功能之一。
这个称为 AnimalTracker? 的 ZCatalog?,可以将 Zope 网站上所有的文件进行编目动作,并且让网站使用者搜寻特定之关键字词。想要为文件进行编目动作,请在 AnimalTracker? 这个 ZCatalog? 点选「搜寻物件」(Find Objects) 介面。
在这个管理介面里,你必须设定想要针对哪些物件格式进行整理动作,由于你想要将所有的 DTML Document 进行编目,所以从「搜寻物件类型」(Find objects of type) 的多重选单中选取 DTML Document,然后点击「搜寻及编目」(Find and Catalog) 按钮。
ZCatalog? 就会从它所在的目录位置,开始搜寻所有的 DTML Document 物件,它会先从所在的目录进行搜寻,然后往下搜寻所有的子目录及它们所包含的子目录。如果你有很多个物件,这个动作会花费较久时间,请耐心等待。
经过一段时间,catalog 便会自动呈现「编目」(Catalog) 介面,并显示一段状态讯息,以便说明刚才完成哪些动作。
在状态讯息底下,会显示完成编目的物件清单,它们全是属于 DTML Document 物件。为了确认这些物件是否就是你想要整理的项目,你可以点击它们,以察看相关细节。
你已经完成搜寻物件以及将它们编目到 ZCatalog? 里的步骤,如今你的文件资料已经存放在 ZCatalog? 资料库里,你可以接着进行后续步骤,即建立一个查询网页,以及显示 ZCatalog? 查询结果的网页。
搜寻及结果表单
建立搜寻与结果的网页表单时,你必须先确定位于 AnimalTracker? 的 catalog 里,并从物件新增选单中点选「Z Search Interface」,在「search ojbect」栏位选单中点选「AnimalTracker」这个 ZCatalog? 物件,画面如图 9-2 所示。
图 9-2: 为 ZCatalog? 物件建立一个查询表单网页
将「Report Id」栏位命名为「SearchResults」,而「Search Input Id」栏位命名为「SearchForm」,确认后会在 AnimalTracker? 这个 ZCatalog? 里产生两个新的 DTML Method,其识别名称分别为「SeachForm」与「SearchResult」。
上述的物件方法被「包含」在 ZCatalog? 里,但它们未被 ZCatalog? 进行「编目」,AnimalTracker 只有针对 DTML Document 进行编目,也就是说,在 catalog 里,搜寻与报告这两个网页物件,只是用来搜寻文件的使用者介面,你可以注意到,搜寻与报告的表单物件,并未列在「编目完成之物件」(Cataloged Objects)介面清单中。
进行 AnimalTracker? 的搜寻动作时,请选择 SearchForm? 这个物件方法,然后点击「检视」(View) 介面。介面表单上有许多栏位项目,ZCatalog 的每一个索引项目都有搭配一个栏位项目,索引的介绍将在稍后的内容中进一步说明。目前为止,你需要使用的栏位项目称为「PrincipiaSearchSource」,其他的栏位内容,可以留着空白,暂时无须在意。
透过在「PrincipiaSearchSource」栏位项目里输入关键字,你就可以搜寻在 AnimalTracker? 里,所有被编目过的文件内容。举例来说,输入「reptiles」这个字词,AnimalTracker 就会展开搜寻动作,并传回一个简单的清单表格,列出有哪些物件内含关键字词「reptiles」。这份清单表格里,应该会包含「carpet python」这个物件。你也可以测试多重字词的搜寻功能,例如输入「reptile amphibian」,这样搜寻结果应该就会同时包含「Chilean four-eyed frog」与「carpet python」。恭喜啦,你已经成功建立一个 catalog,将编目完成的文件存放于内,并透过简单的网页来搜寻它们。
设定编目物件
catalog 强大而复杂的搜寻功能,还远胜于你刚所看到的部份。且让我们瞧瞧 catalog 储存资讯的方法,如此一来,将能协助你利用 catalog 提供所需的搜寻结果。
定义索引ZCatalog? 将物件的相关资讯与它们的内容,储存在一个称为「索引」的快速资料库里。对于大量的资讯内容,索引能够非常快速地进行存取,你可以建立多个不同的索引,分别记录物件的不同资讯,举例来说,你可以有一个记录 DTML Document 内容资讯的索引,也可以有另一个记录特定属性的物件索引。
当你搜寻一个 ZCatalog? 时,你并不是针对所有物件逐一搜寻,如果你的物件数量众多,这样的方式很可能会花费太多时间。在进行 ZCatalog? 搜寻动作之前,它会检视你的物件,并且记录你有意进行的查询方式,这样的过程称为「索引动作」。完成这样的过程后,你可以针对某些特定条件进行搜寻,ZCatalog 会传回满足你所指定条件下的物件结果。
做个比喻,ZCatalog 的索引方式,就像是书籍末尾所附的索引内容,举例来说,在一本书的索引部份,你可能会看到 Python 关键字词的显示方式:
Python: 23, 67, 227
表示 Python 这个字词出现在其中的三页里。Zope 环境里的索引,其运作方式和这样的作法相似,只是它把搜寻的关键字词,例如此处的 Python,对应到一个内含物件清单的串列里,而非一些书籍的页数。
在 Zope 2.4 版本里,可以透过一个新的「可嵌式」索引介面,来管理 catalog 里的索引新增与移除动作,如图 9-3 所示:
图 9-3: 索引管理介面
在索引介面里,你可以看到一些为 ZCatalog? 预先定义好的索引项目,每个索引项目都有一个名称,例如「PrincipiaSearchSource」,另外还有一个类型,例如「TextIndex」。
当你为一个物件进行编目动作时,catalog 会按照索引逐一检查该物件,在查询物件资料时,catalog 会搭配系统的属性设定与物件方法,举例来说,以 PrincipiaSearchSource? 索引项目来对 DTML Document 进行编目时,catalog 会呼叫每个文件的 PrincipiaSearchSource? 物件方法,并将结果记录到 PrincipiaSearchSource? 索引里,如果 catalog 无法找到索引项目所要搭配的属性设定或物件方法,那么它就会忽略不顾。换句话说,就算一个物件并不能支援某个索引的查询动作,那也没关系。索引的类型有下列四种: TextIndex?针对文件内容进行搜寻。如果你想要进行??撌j寻,应该使用这类索引。
FieldIndex?针对物件之特定设定值进行搜寻。如果你想要搜寻日期、数字、或特定字串时,应该使用这类索引。
KeywordIndex?针对一群特定设定值进行搜寻。这个索引项目和 FieldIndex? 类似,但它可以让你搜寻一群设定值,而非只是一个设定值。
PathIndex?针对包含特定 URL 路径内容的物件进行搜寻。举例来说,你可以搜寻路径以/Animals/Zoo 为开始的所有物件。
我们在后续的说明当中,会更清楚地比较这些不同索引项目的差别。现在,已经可以从 ZCatalog? 里的索引介面来建立索引项目,你可以为一个新的索引项目输入它的「名称」(name) 与「类型」(type),这样就可以在 ZCatalog? 里建立一个新的空白索引项目。若要为这个索引项目增加内容资讯,你必须点选「进阶」(Advanced) 介面,并点击「更新编目」(Update Catalog) 按钮,如果你想要进行编目的物件数量众多,那么重新编目的动作,可能会跑上一阵子。
想要从 catalog 里移除索引项目,可以选择索引项目,然后点击「删除」(Remove index) 按钮,这样就可以删除索引项目,以及里头的所有索引内容,不过,按照 Zope的惯例,这项动作还是可以复原的。
定义诠释资料ZCatalog? 不仅可以为物件进行索引动作,也可以在一个表单式资料库里储存物件资讯,这个资料库称为「诠释资料表格」(Meta-Data Table)。诠释资料表格的运作方式,和关连式资料库相似,它包括一个或多个栏位 (column),而栏位则定义了表格的纲要 (schema)。这个表格里记录着特定编目物件的内容资讯,你的诠释资料栏位,不必要与 catalog 的索引项目一致,索引项目能够让你进行搜寻,诠释资料则能够让你进行查询结果的报告。
诠释资料表格对于产生查询结果报告,相当具有帮助,对于查询结果报告里的物件项目,它能记录其相关资讯,举例来说,如果你建立了一个称为「absolute_url」的诠释资料表格栏位,在查询结果报告中,你就可以利用该项栏位资料,为查询到的物件项目建立连结。
想要增加一个新的诠释资料表格栏位,请在「诠释资料表格」介面里,输入栏位名称,然后点击「新增」(Add) 按钮,想要从诠释资料表格移除一个栏位,选择栏位项目前的检查方格,然后击「删除」(Delete) 按钮,这样就可以删除栏位项目,以及所有的内容资料。同样的,按照惯例,这项动作还是可以复原的。接下来,我们将更细部地了解搜寻 catalog 的方法。
编目物件的搜寻方式你可以输入搜寻条件来对 catalog 进行搜寻动作,这些搜寻条件用以描述你想要的查询方式,catalog 可以透过网页方式来取得查询内容,或者你可以直接从 DTML 或 Python 程式传送查询内容。在回应搜寻要求时,catalog 会传回一串清单记录,上头正是符合查询方式的物件内容。
以表单进行搜寻动作利用 Z Search Interface 可以建立一个很简单的查询表单,以及一个很简单的报告表单,不过,它们倒是深入了解 catalog 的好起点,藉以知道 catalog 查询的运作原理,以及你如何能客制化或延伸自己的搜寻介面。
假设你有个 catalog 记录 News Item 资讯,每个 News Item 都有内容 (content)、作者 (author)、日期 (date) 的资料,刚好也有三个索引项目配合这三个属性。content 的索引类型是 TextIndex?,而 date 与 author 的索引类型都是 FieldIndex?。下列是一个搜寻表单范例,可以让你进行查询动作:
<dtml-var standard_html_header>
<form action="Report" method="get">
<h2><dtml-var document_title></h2>
Enter query parameters:<table>
<tr><th>Content</th>
<td><input name="content" width=30 value=""></td></tr>
<tr><th>Author</th>
<td><input name="author" width=30 value=""></td></tr>
<tr><th>Date</th>
<td><input name="date" width=30 value=""></td></tr>
<tr><td colspan=2 align=center>
<input type="SUBMIT" value="Submit Query">
</td></tr>
</table>
</form>
<dtml-var standard_html_footer>
这个表单包含三个输入栏位,分别命名为「content」、「author」、「date」。注意到,它们的命名方式必须和 catalog 的索引项目命名一致,如此才能顺利找到索引资料。下列则是一个配合上述查询表单所用的报告表单范例:
<dtml-var standard_html_header>
<table>
<dtml-in NewsCatalog>
<tr>
<td><dtml-var author></td>
<td><dtml-var date></td>
</tr>
</dtml-in>
</table>
<dtml-var standard_html_footer>
这里有些运作细节,值得再做进一步的说明,整个运作方式的核心项目是在 in 的标签区段里:
<dtml-in NewsCatalog>
此一标签指令会呼叫 NewsCatalog? 这个 catalog 物件。值得注意的是,在这里,查询表单里完全不需要特别指明参数 (content, author, date),Zope 会自动比对查询表单的参数,然后再交给 catalog 物件。你所要进行的动作,就是注意在报告表单中是否正确呼叫 NewsCatalog? 即可。
以 Python 命令稿进行搜寻动作藉由 DTML 语言,从查询表单来搜寻 calog,变得相当简单。在大多数的情况下,DTML 会自动检查你的查询参数是否正确传给 catalog。
有时候,你可能会不想要透过网页表单的方式来搜寻 catalog,举例来说,假设你想要在 ZopeZoo? 网站上,新增一个导引项目,它能针对你正在浏览的园区分类,显示与区内动物相关的新闻内容。你已经知道,ZopeZoo 网站是由 folder 所组成,里头依照动物种类分成不同园区,每个 folder 的 id 就是分类名称,代表里头存放特定物种或是动物的资讯。假设你想设计一个导引资讯,显示不同园区内,动物的相关新闻项目,下列就是一个称为「relevantSectionNews」的 script 程式,它会搭配现有目录 id 为作为变数资料,传入 catalog 进行查询::
## Script (Python) "relevantSectionNews" ## """ Returns news relevant to the current folder's id """
id=context.getId()
return context.NewsCatalog?({content : id})
这个 script 会以类似物件方式呼叫的作法,向 NewsCatalog? 进行查询动作,呼叫 catalog 时,它会要求传入一个映射物件 (mapping) 当作是第一个变数。变数会对映到一个 index 的名称,并将你想要查询的关键字词传入,在本例中,进行查询的是 content 这个 index,含有现行 folder 名称的所有新闻项目将被找出来。想要在导引项目里应用这个程式,只要编辑 ZopeZoo? 网站的 standard_html_header,将 relevantSectionNews 这个 script 加进去:
<html>
<body>
<dtml-var style_sheet>
<dtml-var navigation>
<ul>
<dtml-in relevantSectionNews>
<li><a href="&dtml-absolute_url;"><dtml-var title></a></li>
</dtml-in>
</ul>
上述的程式写法,是假定你事先已经在 NewsCatalog? 里,定义好「absolute_url」与「title」的诠释资料栏位。现在,当你在不同的园区位置,网站导引项目就会显示一个简单的新闻项目清单,内容包含现行园区动物的名称。
搜寻与索引的细部解说前面的内容里,已经提到 catalog 支援三种索引类型,亦即「TextIndex」、「FieldIndex」、「KeywordIndex」,让我们进一步地认识它们,以了解它们有何用处,以及如何应用来进行搜寻。
TextIndex? 的搜寻方式TextIndex? 用于进行文字索引,完成索引后,你可以按照索引来搜寻包含特定字词的物件。TextIndex 支援多种搜寻语法,可以进行更进阶的搜寻功能,而不只是寻找一个字词。ZCatalog 的 TextIndex? 有下列功能:
- 「布林表示式」的搜寻功能,就像「word1 AND word2」方式,可以搜寻同时包含「word1」与「word2」的所有物件,可使用的布林运算子,包括 AND、OR、AND NOT。
- 利用括号可控制搜寻顺序,就像「(word1 AND word2) OR word3)」方式,可以传回包含「word1」及「word2」,或者只包含「word3」的物件。
- 如果你使用「词汇」(Vocabulary) 这个特别的物件项目 (稍后解释),你就可以搭配万用字元来搜寻,就像「Z*」方式,可以传回以「Z」开头的所有字词。
上述的进阶功能,都可以混合搭配,举例来说,「((bob AND uncle) AND NOT Zoo*)」方式,可以传回的物件会包含「bob」与「uncle」,但不包含「Zoo」开头的字词,像是「Zoologist」、「Zoology」或「Zoo」本身。
搭配这些进阶功能来查询一个 TextIndex?,其运作方式就和之前介绍过的简易功能类似。在 DTML Document 的搜寻范例中,你可以输入「Koala And Lion」,就可以查询到有关 Koala 与 Lion 的所有文件。透过 Python 程式,搭配进阶功能来查询一个 TextIndex?,其运作方式也是类似,假设你想要修改 relevantSectionNews 命令稿内容,把包含关键字词「catastrophic」的 News Item 给剔除:
## Script (Python) "relevantSectionNews"
##
""" Returns relevant, non-catastropic news """
id=context.getId()
return context.NewsCatalog<a class="new" href="http://members.czug.org/zope/zopebook/X_e5_86_85_e5_ae_b9_e7_9a_84_e6_9f_a5_e8_af_a2_e5_92_8c_e5_88_86_e7_b1_bb/createform?page=NewsCatalog" title="create this page">?</a>(
{'content' : id + ' AND NOT catastrophic'}
)
TextIndex? 的功能相当强大,当搭配本章后面所介绍的「自动编目方式」(Automatic Cataloging) 时,随着物件的建立与编辑,它们仍然可以提供自动化的文件搜寻能力。
词汇vocabulary 是配合 TextIndex? 所使用的,
FieldIndex? 的搜寻方式FieldIndex? 和 TextIndex? 有点不同,对于物件项目,TextIndex 会将被搜寻的资料,以文字的型态来处理,例如,News Item 里的内容资料就是如此处理。也就是说,它会把文件内容拆解成一个个字词,然后再将它们各别地进行索引。
FieldIndex? 并不会去拆解它所要查询的资料,相反地,它们将想要查询的资料,整笔进行索引动作。如此一来,这项功能就很适合于,追踪那些包含固定字串资料的物件了。
在之前的 News Item 范例中,你所建立的「date」与「author」,就是两个 FieldIndex? 索引项目,但是,现有的搜寻介面,并不适合用来搭配它们,为了更有效地使用这些索引项目,你必须将搜寻表单做些客制化。在实际动手前,我们先考虑一些使用索引时的状况。
date 这个 index 可以让你依据建立时间来搜寻新闻项目,但现有的搜寻表单却显得不好用,因为你必须在查询表格里,输入想要查询的「准确」时间,还得精准到秒的单位才行。显然,这种方式并不方便,比较好的方法,是以时间「范围」来查询,例如,最近二十四小时内所新增的新闻项目,或是这个月以来的所有新闻项目。
author 这个 index 可以让你依据特定作者名称来搜寻新闻项目,但除非你明确知道想要找的作者名称,不然可能会得不到结果。较好的办法,应该是由 author 这个 index 所建立的作者清单中,让使用者以选择方式来查询。
FieldIndex? 就是设计来处理范围查询与索引清单查询的工具,想要应用这项功能,你只需要简单修改一下查询表单。让我们先试试第一个例子,如何以日期范围来进行查询。
和 TextIndex? 类似的是,FieldIndex 也可以传入一些特别设定值,以便执行一些功能,使用的时候,你必须以表单项目的方式,传入并转成 catalog 的查询资讯。下列的查询表单,取自于先前「以表单进行搜寻动作」的范例,但增加了一些新的表单项目,以便能够执行所需的功能,像是查询「昨日至今」、「上周至今」、「上月至今」、「去年至今」、「全部」所修改过的新闻项目:
<dtml-var standard_html_header>
<form action="Report" method="get">
<h2><dtml-var document_title></h2>
Search for News Items:<table>
<tr><th>Content</th>
<td><input name="content" width=30 value=""></td></tr>
<tr><th>Author</th>
<td><input name="author" width=30 value=""></td></tr>
<tr>
<td><p>modified since:</p></td>
<td>
<input type="hidden" name="date_usage" value="range:min">
<select name="date:date">
<option value="<dtml-var expr="ZopeTime(0) >">Ever</option>
<option value="<dtml-var expr="ZopeTime() - 1 >">Yesterday</option>
<option value="<dtml-var expr="ZopeTime() - 7 >">Last Week</option>
<option value="<dtml-var expr="ZopeTime() - 30 >">Last Month</option>
<option value="<dtml-var expr="ZopeTime() - 365 >">Last Year</option>
</select>
</td>
</tr>
<tr><td colspan=2 align=center>
<input type="SUBMIT" value="Submit Query">
</td></tr>
</table>
</form>
<dtml-var standard_html_footer>
本段范例的画面结果,将会类似图 9-4 所示。
图 9-4: 日期属性的范围搜寻
这份 HTML 表单中,date 的格式已和原本的查询表单有所不同。它提供一个选单,让你可以选择一个日期,而不再只是一个输入栏位。但是要记得,这是个「范围」的搜寻方式,你能看得出来,是哪个部份让 date 这个 FieldIndex? 知道要进行范围搜寻的吗?答案在这里:
<input type="hidden" name="date_usage" value="range:min">
这里用到的是一个叫作 hidden 的 HTML 表格标签特别项目,它并不会在你所看见的查询表单中出现,但在你确认送出表单时,它还是会传递资料给 Zope。这个特别的标签项目名称定为 date_usage,它会通知 date 这个 FieldIndex?,date 表单项目里的传回值属于「最小范围边界」,意思是说,FieldIndex 不会只传回符合选定时间点的物件而是从选定时间点开始,包括之后时间的所有物件。
每一个 FieldIndex? 都可以指定范围设定方式,只要在 index 名称之后,加上 "_usage" 字尾,指定额外的搜寻变数即可。除了指定最小范围边界外,你可以指定「最大范围边界」,将上述的 hidden 表单项目修改如下:
<input type="hidden" name="date_usage" value="range:max">
如此一来,就会让查询表单传回特定时间点之前修改的新闻项目,而非之后的了。
"_usage" 的语法也可以用在呼叫 catalog 的 script 上,就像下列这个叫作 relevantRecentSectionNews 的 script 范例:
## Script (Python) "relevantRecentSectionNews"
##
""" Return relevant, and recent, news for this section """
id=context.getId()
return context.NewsCatalog<a class="new" href="http://members.czug.org/zope/zopebook/X_e5_86_85_e5_ae_b9_e7_9a_84_e6_9f_a5_e8_af_a2_e5_92_8c_e5_88_86_e7_b1_bb/createform?page=NewsCatalog" title="create this page">?</a>(
{'content' : id,
'date' : ZopeTime<a class="new" href="http://members.czug.org/zope/zopebook/X_e5_86_85_e5_ae_b9_e7_9a_84_e6_9f_a5_e8_af_a2_e5_92_8c_e5_88_86_e7_b1_bb/createform?page=ZopeTime" title="create this page">?</a>() ? 7,
'date_usage' : 'range:min',
}
)
这个 script 的运作方式,和之前旧版 relevantSectionNews 类似,差别在于它只会传回一周以来的新闻项目。
你也可以同时指定最小及最大范围边界,不过,有个地方要特别小心。一般而言,如果你未指定,或是只指定一个范围边界,ZCatalog 会使用你所传入的数值当作查询条件,如果你指定两个范围边界的话,ZCatalog 就需要两个数值,而非只有一个。我们将上述 relevantRecentSectionNews 这个 script 略作修改,以便传入一个日期物件的串列 (list),而非单一的数值:
## Script (Python) "relevantRecentSectionNews"
##
"""
Return relevant news modified in the last month, but not the
last week
"""
id=context.getId()
return context.NewsCatalog<a class="new" href="http://members.czug.org/zope/zopebook/X_e5_86_85_e5_ae_b9_e7_9a_84_e6_9f_a5_e8_af_a2_e5_92_8c_e5_88_86_e7_b1_bb/createform?page=NewsCatalog" title="create this page">?</a>(
{'content' : id,
'date' : [ZopeTime() - 30, ZopeTime() - 7]<a class="new" href="http://members.czug.org/zope/zopebook/X_e5_86_85_e5_ae_b9_e7_9a_84_e6_9f_a5_e8_af_a2_e5_92_8c_e5_88_86_e7_b1_bb/createform?page=ZopeTime%28%29%20-%2030%2C%20ZopeTime%28%29%20-%207" title="create this page">?</a>,
'date_usage' : 'range:min:max',
}
)
这个 script 会传回所有上月以来修改的相关新闻项目,但不包括上周以内的部份。使用两个范围边界时,特别重要的是,要确定你所传入数值的顺序,是否与范围边界的顺序正确相符,如果你不小心把最小和最大的边界设定调换,或忘了也把时间数值调换,那么就会得到空白的查询结果,因为你的查询条件变成没有意义了 (指定一个最小值,却比最大值来得大)。
KeywordIndex? 的搜寻方式
KeywordIndex? 将物件的一串关键字词进行索引,
可透过关键字词来查询相关物件。
假设你有一些 Image 物件, 它们的物件属性里, 有个项目是「topics」, 其属性类型是 lines, 用来记录某一张图形的相关主题项目, 举例来说, 有一张维多利亚女王的相片, 其 topics 属性被设定为「Portraits」、「19th Century」、「Women」这些关键字。
这些 topics 内容可用来为 Image 物件进行分类, 根据它的 topics 属性值,每个 Image 可以被分到一个或多个分类里, 举例来说,维多利亚女王的相片,可以归到三个分类里, 而且可以透过三种查询条件中的任一种找到。
你可以使用 KeywordIndex? 来为 topics 属性项目进行搜寻,
在 ZCatalog? 里定义一个名称为 topics 的 KeywordIndex?, 然后选择 Image 进行编目动作。 现在透过建立一个查询表单, 在 topics 栏位输入 Portraits, 你应该可以找到所有人像相关的图形物件, 或是透过输入 19th Century 的关键字查询, 而找到所有关于十九世纪的图片。
有项重要的观念要了解,就是同一张图片,可以被归到不止一个分类里。 在为物件进行搜寻与分类时,这点能够为你带来比 FieldIndex? 更多的弹性, 使用 FieldIndex? 的话,你的维多利亚女王相片只能用一种方式来分类, 使用 KeywordIndex? 的话,就可以被多种不同方式所分类。
通常你会使用一个小的清单内容,来搭配 KeywordIndex?, 在这种情况下,你可能会需要使用 uniqueValuesFor 这个物件方法, 以便建立一个客制化的查询表单。 举例来说,下列是一段 DTML 程式码范例,
可用来建立一个多重项目选单,内含所有 topics 索引的资料值:
<select name="topics:list" multiple>
<dtml-in expr="uniqueValuesFor('topics')">
<option value="&dtml-sequence-item;"><dtml-var sequence-item></option>
</dtml-in>
</select>
使用这个查询表单,你可以提供使用者一个正确的查询项目范围, 你可以选择任意个 topics,而 Zope 会找到所有符合的物件, 不管是满足其中一个或是多个资料条件。
PathIndex? 的搜寻方式
PathIndex? 可以让你搜寻物件的所在路径。
假设你有个物件,其所在路径是 /zoo/animals/Africa/tiger.doc, 你可以透过多样的路径查询方式找到它: /zoo、或是 /zoo/animals、或是 /zoo/animals/Africa。 也就是说,一个 PathIndex? 可以让你找寻某个 folder (及其底层) 的物件。
如果你将许多相关的物件,放置在相同的目录里, 那么就可以应用 PathIndex? 来快速找寻这些物件,举例来说:
<h2>Lizard Pictures</h2>
Image,
path=/Zoo/Animals/Lizard)">
上述的查询内容,会向一个 catalog 寻找所有的图形物件, 它们的位置必须在 /Zoo/Animals/Lizard 目录里,或是该目录底下。 查询到的结果会为每一个图形物件建立一个连结。
取决于网站里安排物件的处理方式,你会发现到底应用 PathIndex? 是否显得有效率。
