将任意值作为对象指标的分值。
项目描述
创建两个文档索引。
>>> from z3c.metrics import testing >>> foo_doc_index = testing.Index() >>> bar_doc_index = testing.Index()
创建一个创建者索引。
>>> creator_index = testing.Index()
设置索引的刻度。刻度的默认值是半衰期为一个单位。对于时间刻度,半衰期为一年。
>>> from z3c.metrics import scale >>> one_year_scale = scale.ExponentialDatetimeScale() >>> foo_doc_index.scale = one_year_scale >>> creator_index.scale = one_year_scale
为第二个文档索引指定两年的半衰期。
>>> two_year_scale = scale.ExponentialDatetimeScale( ... scale_unit=scale.one_year*2) >>> bar_doc_index.scale = two_year_scale
创建一个自度量,该度量对对象本身的创建日期进行评分。
>>> from z3c.metrics import interfaces, metric >>> self_metric = metric.SelfMetric( ... field_name="created", interface=interfaces.ICreated)
注册自度量事件处理器,以便它们在文档本身上运行以进行自己的评分。
>>> from zope import component >>> component.provideHandler( ... factory=self_metric.initSelfScore, ... adapts=[testing.IDocument, interfaces.IAddValueEvent]) >>> component.provideHandler( ... factory=self_metric.removeSelfScore, ... adapts=[testing.IDocument, interfaces.IRemoveValueEvent])
创建一个其他度量,该度量对后代的创建日期进行评分。
>>> desc_metric = metric.OtherMetric( ... interface=interfaces.ICreated, ... field_name="created", field_callable=True)
注册其他度量事件处理器,以便它们在文档的后代上运行以进行文档评分。
>>> component.provideHandler( ... factory=desc_metric.addOtherValue, ... adapts=[testing.IDescendant, ... interfaces.IAddValueEvent, ... testing.IDocument]) >>> component.provideHandler( ... factory=desc_metric.removeOtherValue, ... adapts=[testing.IDescendant, ... interfaces.IRemoveValueEvent, ... testing.IDocument])
创建一个初始化度量,该度量初始化新创建者的评分。
>>> from zope.app.security import interfaces as security_ifaces >>> init_metric = metric.InitMetric()
注册初始化度量事件处理器,以便在创建者和删除者添加和删除时运行。
>>> component.provideHandler( ... factory=init_metric.initSelfScore, ... adapts=[security_ifaces.IPrincipal, ... interfaces.IInitScoreEvent]) >>> component.provideHandler( ... factory=init_metric.removeSelfScore, ... adapts=[security_ifaces.IPrincipal, ... interfaces.IRemoveValueEvent])
注册其他度量事件处理器,以便在文档上运行以进行创建者评分。
>>> other_metric = metric.OtherMetric( ... field_name="created", interface=interfaces.ICreated)>>> from zope.app.security import interfaces as security_ifaces >>> component.provideHandler( ... factory=other_metric.addOtherValue, ... adapts=[testing.IDocument, ... interfaces.IAddValueEvent, ... security_ifaces.IPrincipal]) >>> component.provideHandler( ... factory=other_metric.removeOtherValue, ... adapts=[testing.IDocument, ... interfaces.IRemoveValueEvent, ... security_ifaces.IPrincipal])
注册其他度量事件处理器,以便在文档的后代上运行以进行创建者评分。
>>> component.provideHandler( ... factory=desc_metric.addOtherValue, ... adapts=[testing.IDescendant, ... interfaces.IAddValueEvent, ... security_ifaces.IPrincipal]) >>> component.provideHandler( ... factory=desc_metric.removeOtherValue, ... adapts=[testing.IDescendant, ... interfaces.IRemoveValueEvent, ... security_ifaces.IPrincipal])
创建一个以创建者为主体的主体。
>>> from z3c.metrics import testing >>> authentication = component.getUtility( ... security_ifaces.IAuthentication) >>> baz_creator = testing.Principal() >>> authentication['baz_creator'] = baz_creator
创建一个根容器。
>>> root = testing.setUpRoot()
在向任何索引添加任何度量之前创建一个文档。
>>> foo_doc = testing.Document() >>> foo_doc.created = scale.epoch >>> foo_doc.creators = ('baz_creator',) >>> root['foo_doc'] = foo_doc
创建一个将被包含在文档评分中的文档的后代。
>>> now = scale.epoch+scale.one_year*2 >>> foo_desc = testing.Descendant() >>> foo_desc.created = now >>> foo_desc.creators = ('baz_creator',) >>> foo_doc['foo_desc'] = foo_desc
索引还没有度量,因此它们对文档没有评分。
>>> foo_doc_index.getScoreFor(foo_doc) Traceback (most recent call last): KeyError: ... >>> bar_doc_index.getScoreFor(foo_doc) Traceback (most recent call last): KeyError: ... >>> creator_index.getScoreFor(baz_creator) Traceback (most recent call last): KeyError: ...
以默认权重将自度量添加到第一个文档索引中。
>>> from z3c.metrics import subscription >>> foo_self_sub = subscription.LocalWeightedSubscription( ... foo_doc_index) >>> component.provideSubscriptionAdapter( ... factory=foo_self_sub.getChangeScoreEngine, ... adapts=[interfaces.IMetric, testing.IDocument, ... interfaces.IChangeScoreEvent]) >>> component.provideSubscriptionAdapter( ... factory=foo_self_sub.getBuildScoreEngine, ... adapts=[interfaces.IMetric, testing.IDocument, ... interfaces.IBuildScoreEvent])
将自度量添加到其他文档索引中,但权重为二。
>>> bar_self_sub = subscription.LocalWeightedSubscription( ... bar_doc_index) >>> bar_self_sub.weight = 2.0 >>> component.provideSubscriptionAdapter( ... factory=bar_self_sub.getChangeScoreEngine, ... adapts=[interfaces.IMetric, ... testing.IDocument, ... interfaces.IChangeScoreEvent]) >>> component.provideSubscriptionAdapter( ... factory=bar_self_sub.getBuildScoreEngine, ... adapts=[interfaces.IMetric, ... testing.IDocument, ... interfaces.IBuildScoreEvent])
也将其他度量添加到文档的子索引中。
>>> bar_desc_sub = subscription.LocalWeightedSubscription( ... bar_doc_index) >>> component.provideSubscriptionAdapter( ... factory=bar_desc_sub.getChangeScoreEngine, ... adapts=[interfaces.IMetric, ... testing.IDocument, ... interfaces.IChangeScoreEvent, ... testing.IDescendant]) >>> component.provideSubscriptionAdapter( ... factory=bar_desc_sub.getBuildScoreEngine, ... adapts=[interfaces.IMetric, ... testing.IDocument, ... interfaces.IBuildScoreEvent, ... testing.IDescendant])
将初始化度量添加到创建者索引中,用于创建者。
>>> creator_init_sub = subscription.LocalWeightedSubscription( ... creator_index) >>> component.provideSubscriptionAdapter( ... factory=creator_init_sub.getChangeScoreEngine, ... adapts=[interfaces.IMetric, ... security_ifaces.IPrincipal, ... interfaces.IChangeScoreEvent]) >>> component.provideSubscriptionAdapter( ... factory=creator_init_sub.getBuildScoreEngine, ... adapts=[interfaces.IMetric, ... security_ifaces.IPrincipal, ... interfaces.IBuildScoreEvent])
将其他度量添加到创建者索引中,对于文档创建者的权重为二。
>>> creator_doc_sub = subscription.LocalWeightedSubscription( ... creator_index) >>> creator_doc_sub.weight = 2.0 >>> component.provideSubscriptionAdapter( ... factory=creator_doc_sub.getChangeScoreEngine, ... adapts=[interfaces.IMetric, ... security_ifaces.IPrincipal, ... interfaces.IChangeScoreEvent, ... testing.IDocument]) >>> component.provideSubscriptionAdapter( ... factory=creator_doc_sub.getBuildScoreEngine, ... adapts=[interfaces.IMetric, security_ifaces.IPrincipal, ... interfaces.IBuildScoreEvent, testing.IDocument])
将其他度量添加到创建者索引中,对于文档子创建者的默认权重。
>>> creator_desc_sub = subscription.LocalWeightedSubscription( ... creator_index) >>> component.provideSubscriptionAdapter( ... factory=creator_desc_sub.getChangeScoreEngine, ... adapts=[interfaces.IMetric, ... security_ifaces.IPrincipal, ... interfaces.IChangeScoreEvent, ... testing.IDescendant]) >>> component.provideSubscriptionAdapter( ... factory=creator_desc_sub.getBuildScoreEngine, ... adapts=[interfaces.IMetric, ... security_ifaces.IPrincipal, ... interfaces.IBuildScoreEvent, ... testing.IDescendant])
为文档构建得分。
>>> foo_doc_index.buildScoreFor(foo_doc) >>> bar_doc_index.buildScoreFor(foo_doc)
现在文档在这两个索引中都有不同的得分。
>>> foo_doc_index.getScoreFor(foo_doc, query=now) 0.25 >>> bar_doc_index.getScoreFor(foo_doc, query=now) 2.0
构建创建者的得分。
>>> creator_index.buildScoreFor(baz_creator)
现在创建者在创建者索引中有得分。
>>> creator_index.getScoreFor(baz_creator, query=now) 1.5
添加一个新的创建者。
>>> qux_creator = testing.Principal() >>> authentication['qux_creator'] = qux_creator
新创建者现在也有正确的得分
>>> creator_index.getScoreFor(qux_creator, query=now) 0.0
创建一个新的文档,包含两个创建者。
>>> bar_doc = testing.Document() >>> bar_doc.created = now >>> bar_doc.creators = ('baz_creator', 'qux_creator') >>> root['bar_doc'] = bar_doc
索引为新文档有得分。
>>> foo_doc_index.getScoreFor(bar_doc, query=now) 1.0 >>> bar_doc_index.getScoreFor(bar_doc, query=now) 2.0 >>> creator_index.getScoreFor(baz_creator, query=now) 3.5 >>> creator_index.getScoreFor(qux_creator, query=now) 2.0
重建时得分相同。
>>> foo_doc_index.buildScoreFor(bar_doc) >>> bar_doc_index.buildScoreFor(bar_doc) >>> creator_index.buildScoreFor(baz_creator) >>> creator_index.buildScoreFor(qux_creator)>>> foo_doc_index.getScoreFor(bar_doc, query=now) 1.0 >>> bar_doc_index.getScoreFor(bar_doc, query=now) 2.0 >>> creator_index.getScoreFor(baz_creator, query=now) 3.5 >>> creator_index.getScoreFor(qux_creator, query=now) 2.0
稍后,为此文档添加两个子文档。
>>> now = scale.epoch+scale.one_year*4 >>> bar_desc = testing.Descendant() >>> bar_desc.created = now >>> bar_doc['bar_desc'] = bar_desc >>> baz_desc = testing.Descendant() >>> baz_desc.created = now >>> bar_doc['baz_desc'] = baz_desc
得分反映了添加。
>>> foo_doc_index.getScoreFor(bar_doc, query=now) 0.25 >>> bar_doc_index.getScoreFor(bar_doc, query=now) 3.0
其他文档的得分也反映了时间的推进。
>>> foo_doc_index.getScoreFor(foo_doc, query=now) 0.0625 >>> bar_doc_index.getScoreFor(foo_doc, query=now) 1.0 >>> creator_index.getScoreFor(baz_creator, query=now) 0.875 >>> creator_index.getScoreFor(qux_creator, query=now) 0.5
重建时得分相同。
>>> foo_doc_index.buildScoreFor(foo_doc) >>> bar_doc_index.buildScoreFor(foo_doc) >>> foo_doc_index.buildScoreFor(bar_doc) >>> bar_doc_index.buildScoreFor(bar_doc) >>> creator_index.buildScoreFor(baz_creator) >>> creator_index.buildScoreFor(qux_creator)>>> foo_doc_index.getScoreFor(foo_doc, query=now) 0.0625 >>> bar_doc_index.getScoreFor(foo_doc, query=now) 1.0 >>> foo_doc_index.getScoreFor(bar_doc, query=now) 0.25 >>> bar_doc_index.getScoreFor(bar_doc, query=now) 3.0 >>> creator_index.getScoreFor(baz_creator, query=now) 0.875 >>> creator_index.getScoreFor(qux_creator, query=now) 0.5
删除一个子文档。
>>> del bar_doc['bar_desc']
得分反映了子文档的删除。
>>> foo_doc_index.getScoreFor(bar_doc, query=now) 0.25 >>> bar_doc_index.getScoreFor(bar_doc, query=now) 2.0
重建时得分相同。
>>> foo_doc_index.buildScoreFor(bar_doc) >>> bar_doc_index.buildScoreFor(bar_doc)>>> foo_doc_index.getScoreFor(bar_doc, query=now) 0.25 >>> bar_doc_index.getScoreFor(bar_doc, query=now) 2.0
删除一个文档。
>>> del root['bar_doc']
文档索引不再有该文档的得分。
>>> foo_doc_index.getScoreFor(bar_doc) Traceback (most recent call last): KeyError: ... >>> bar_doc_index.getScoreFor(bar_doc) Traceback (most recent call last): KeyError: ...
创建者索引反映了变化。
>>> creator_index.getScoreFor(baz_creator, query=now) 0.375 >>> creator_index.getScoreFor(qux_creator, query=now) 0.0
XXX
例如,一个度量可能收集对象本身创建的日期。另一个度量可能收集某些类型的子文档创建的日期。另一个度量可能收集某些类型子文档的评分值。
索引使用一个或多个度量来提供对象规范化值的有效查找。此类值的常见用途是对一组对象进行排序。索引存储的对象得分是每个度量确定的得分的总和。
XXX度量
度量定义了构成给定度量索引中对象得分的值。度量可以增量地更新对象的得分,因此只能使用在更改时可以检索到先前和新的值的值。
例如,一个值可能是一个子文档的创建日期。当此类值更改时,度量可以假设没有先前的值。同样,当此类对象被删除时,度量必须能够在删除之前从对象中检索创建日期,以便进行增量调整。
如果度量的值是可变的,则此问题尤为关注。度量必须始终被告知该值何时以这种方式更改,以便它能够访问先前和新的值。这通常通过度量订阅的处理程序事件来完成。
度量是知道如何查找给定对象的度量值的组件。
请注意,如果我们不依赖事件顺序,则从头开始构建对象得分需要显式初始化索引并确保没有事件处理程序会初始化构建得分事件得分。否则,初始化事件处理程序可能在其他添加值事件之后被调用,从而抵消它们的效果。
变更日志
0.1 - 2009-04-08
初始发布