Skip to content

Commit 8074dee

Browse files
committed
Update grpc, separate Time and Numeric decay
1 parent c5d7c23 commit 8074dee

8 files changed

Lines changed: 198 additions & 73 deletions

File tree

weaviate/collections/classes/grpc.py

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class Rerank(_WeaviateInput):
245245

246246

247247
@dataclass
248-
class _DecayFunction:
248+
class _TimeDecayFunction:
249249
property: str
250250
origin: str
251251
scale: str
@@ -254,6 +254,16 @@ class _DecayFunction:
254254
decay_value: Optional[float] = None
255255

256256

257+
@dataclass
258+
class _NumericDecayFunction:
259+
property: str
260+
origin: float
261+
scale: float
262+
offset: Optional[float] = None
263+
curve: Optional[str] = None
264+
decay_value: Optional[float] = None
265+
266+
257267
@dataclass
258268
class _PropertyValueFunction:
259269
property: str
@@ -263,7 +273,8 @@ class _PropertyValueFunction:
263273
@dataclass
264274
class _BoostCondition:
265275
filter: Optional[Any] = None # FilterReturn
266-
decay: Optional[_DecayFunction] = None
276+
time_decay: Optional[_TimeDecayFunction] = None
277+
numeric_decay: Optional[_NumericDecayFunction] = None
267278
property_value: Optional[_PropertyValueFunction] = None
268279
weight: Optional[float] = None
269280

@@ -338,37 +349,36 @@ def filter(
338349
return _Boost(conditions=[_BoostCondition(filter=filter)], weight=weight, depth=depth)
339350

340351
@staticmethod
341-
def decay(
352+
def time_decay(
342353
property: str,
343354
*,
344-
origin: Optional[Union[str, int, float, datetime]] = None,
345-
scale: Union[str, int, float, timedelta],
346-
offset: Optional[Union[str, int, float, timedelta]] = None,
355+
origin: Optional[Union[str, datetime]] = None,
356+
scale: Union[str, timedelta],
357+
offset: Optional[Union[str, timedelta]] = None,
347358
curve: Optional[Union[_BoostCurve, str]] = None,
348359
decay_value: Optional[float] = None,
349360
weight: Optional[float] = None,
350361
depth: Optional[int] = None,
351362
) -> _Boost:
352-
"""Apply distance-based decay scoring from an origin value.
363+
"""Apply time-based decay scoring from an origin date.
353364
354365
Args:
355-
property: The property name to compute distance from.
356-
origin: The origin point. Use "now" for current time, a datetime for a specific time,
357-
or a numeric value for number properties. Defaults to "now" for date properties.
358-
scale: Distance from origin where score equals decay_value. Use timedelta for date
359-
properties (e.g. timedelta(days=7)) or a number for numeric properties. String
360-
shorthands like "7d", "24h" are also accepted.
366+
property: The date property name to compute distance from.
367+
origin: The origin point. Use "now" for current time or a datetime for a specific time.
368+
Defaults to "now".
369+
scale: Distance from origin where score equals decay_value. Use timedelta
370+
(e.g. timedelta(days=7)) or a string shorthand like "7d", "24h".
361371
offset: Documents within this distance from origin get full score (default "0").
362372
Accepts the same types as scale.
363373
curve: Decay curve type: `Boost.Curve.EXPONENTIAL` (default), `Boost.Curve.GAUSSIAN`, or `Boost.Curve.LINEAR`.
364374
decay_value: Score at scale distance from origin (default 0.5).
365375
weight: Blending weight [0,1] controlling how much the rank affects final scores.
366-
depth: Number of results to rescore (default 100, max 10000). Higher values improve accuracy at the cost of performance.
376+
depth: Number of results to rescore (default 100, max 10000).
367377
"""
368378
return _Boost(
369379
conditions=[
370380
_BoostCondition(
371-
decay=_DecayFunction(
381+
time_decay=_TimeDecayFunction(
372382
property=property,
373383
origin=_decay_value_to_str(origin) if origin is not None else "",
374384
scale=_decay_value_to_str(scale),
@@ -382,6 +392,47 @@ def decay(
382392
depth=depth,
383393
)
384394

395+
@staticmethod
396+
def numeric_decay(
397+
property: str,
398+
*,
399+
origin: float,
400+
scale: float,
401+
offset: Optional[float] = None,
402+
curve: Optional[Union[_BoostCurve, str]] = None,
403+
decay_value: Optional[float] = None,
404+
weight: Optional[float] = None,
405+
depth: Optional[int] = None,
406+
) -> _Boost:
407+
"""Apply numeric distance-based decay scoring from an origin value.
408+
409+
Args:
410+
property: The numeric property name to compute distance from.
411+
origin: The origin point (numeric value).
412+
scale: Distance from origin where score equals decay_value.
413+
offset: Documents within this distance from origin get full score (default 0).
414+
curve: Decay curve type: `Boost.Curve.EXPONENTIAL` (default), `Boost.Curve.GAUSSIAN`, or `Boost.Curve.LINEAR`.
415+
decay_value: Score at scale distance from origin (default 0.5).
416+
weight: Blending weight [0,1] controlling how much the rank affects final scores.
417+
depth: Number of results to rescore (default 100, max 10000).
418+
"""
419+
return _Boost(
420+
conditions=[
421+
_BoostCondition(
422+
numeric_decay=_NumericDecayFunction(
423+
property=property,
424+
origin=float(origin),
425+
scale=float(scale),
426+
offset=float(offset) if offset is not None else None,
427+
curve=curve.value if isinstance(curve, _BoostCurve) else curve,
428+
decay_value=decay_value,
429+
)
430+
)
431+
],
432+
weight=weight,
433+
depth=depth,
434+
)
435+
385436
@staticmethod
386437
def property(
387438
name: str,
@@ -423,15 +474,15 @@ def blend(
423474
and the `weight` parameter here controls the overall blending strength.
424475
425476
Args:
426-
*ranks: Rank objects created via `Boost.filter()`, `Boost.decay()`, or `Boost.property()`.
477+
*ranks: Rank objects created via `Boost.filter()`, `Boost.time_decay()`, `Boost.numeric_decay()`, or `Boost.property()`.
427478
weight: Overall blending weight [0,1] for combining primary search and rank scores.
428479
depth: Number of results to rescore (default 100, max 10000). Higher values improve accuracy at the cost of performance.
429480
"""
430481
conditions: List[_BoostCondition] = []
431482
for r in ranks:
432483
for cond in r.conditions:
433484
if cond.weight is None and r.weight is not None:
434-
cond = _BoostCondition(filter=cond.filter, decay=cond.decay, property_value=cond.property_value, weight=r.weight)
485+
cond = _BoostCondition(filter=cond.filter, time_decay=cond.time_decay, numeric_decay=cond.numeric_decay, property_value=cond.property_value, weight=r.weight)
435486
conditions.append(cond)
436487
return _Boost(conditions=conditions, weight=weight, depth=depth)
437488

weaviate/collections/grpc/query.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,11 @@ def _metadata_to_grpc(self, metadata: _MetadataQuery) -> search_get_pb2.Metadata
552552
"sqrt": search_get_pb2.PROPERTY_VALUE_MODIFIER_SQRT,
553553
}
554554

555+
def __resolve_curve(self, curve: Optional[str]) -> int:
556+
if curve is None:
557+
return search_get_pb2.DECAY_CURVE_EXPONENTIAL
558+
return self._CURVE_TO_PROTO.get(curve, search_get_pb2.DECAY_CURVE_EXPONENTIAL)
559+
555560
def __boost_to_grpc(
556561
self, boost: Optional[_Boost]
557562
) -> Optional[search_get_pb2.Boost]:
@@ -562,17 +567,26 @@ def __boost_to_grpc(
562567
grpc_cond = search_get_pb2.BoostCondition(weight=cond.weight)
563568
if cond.filter is not None:
564569
grpc_cond.filter.CopyFrom(_FilterToGRPC.convert(cond.filter))
565-
elif cond.decay is not None:
566-
grpc_cond.decay.CopyFrom(
567-
search_get_pb2.DecayFunction(
568-
property=cond.decay.property,
569-
origin=cond.decay.origin,
570-
scale=cond.decay.scale,
571-
offset=cond.decay.offset,
572-
curve=self._CURVE_TO_PROTO.get(
573-
cond.decay.curve, search_get_pb2.DECAY_CURVE_EXPONENTIAL
574-
) if cond.decay.curve is not None else search_get_pb2.DECAY_CURVE_EXPONENTIAL,
575-
decay_value=cond.decay.decay_value,
570+
elif cond.time_decay is not None:
571+
grpc_cond.time_decay.CopyFrom(
572+
search_get_pb2.TimeDecayFunction(
573+
property=cond.time_decay.property,
574+
origin=cond.time_decay.origin,
575+
scale=cond.time_decay.scale,
576+
offset=cond.time_decay.offset,
577+
curve=self.__resolve_curve(cond.time_decay.curve),
578+
decay_value=cond.time_decay.decay_value,
579+
)
580+
)
581+
elif cond.numeric_decay is not None:
582+
grpc_cond.numeric_decay.CopyFrom(
583+
search_get_pb2.NumericDecayFunction(
584+
property=cond.numeric_decay.property,
585+
origin=cond.numeric_decay.origin,
586+
scale=cond.numeric_decay.scale,
587+
offset=cond.numeric_decay.offset,
588+
curve=self.__resolve_curve(cond.numeric_decay.curve),
589+
decay_value=cond.numeric_decay.decay_value,
576590
)
577591
)
578592
elif cond.property_value is not None:

weaviate/proto/v1/v4216/v1/search_get_pb2.py

Lines changed: 12 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

weaviate/proto/v1/v4216/v1/search_get_pb2.pyi

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,16 +347,18 @@ class Boost(_message.Message):
347347
def __init__(self, conditions: _Optional[_Iterable[_Union[BoostCondition, _Mapping]]] = ..., weight: _Optional[float] = ..., depth: _Optional[int] = ...) -> None: ...
348348

349349
class BoostCondition(_message.Message):
350-
__slots__ = ("filter", "decay", "property_value", "weight")
350+
__slots__ = ("filter", "time_decay", "property_value", "numeric_decay", "weight")
351351
FILTER_FIELD_NUMBER: _ClassVar[int]
352-
DECAY_FIELD_NUMBER: _ClassVar[int]
352+
TIME_DECAY_FIELD_NUMBER: _ClassVar[int]
353353
PROPERTY_VALUE_FIELD_NUMBER: _ClassVar[int]
354+
NUMERIC_DECAY_FIELD_NUMBER: _ClassVar[int]
354355
WEIGHT_FIELD_NUMBER: _ClassVar[int]
355356
filter: _base_pb2.Filters
356-
decay: DecayFunction
357+
time_decay: TimeDecayFunction
357358
property_value: PropertyValueFunction
359+
numeric_decay: NumericDecayFunction
358360
weight: float
359-
def __init__(self, filter: _Optional[_Union[_base_pb2.Filters, _Mapping]] = ..., decay: _Optional[_Union[DecayFunction, _Mapping]] = ..., property_value: _Optional[_Union[PropertyValueFunction, _Mapping]] = ..., weight: _Optional[float] = ...) -> None: ...
361+
def __init__(self, filter: _Optional[_Union[_base_pb2.Filters, _Mapping]] = ..., time_decay: _Optional[_Union[TimeDecayFunction, _Mapping]] = ..., property_value: _Optional[_Union[PropertyValueFunction, _Mapping]] = ..., numeric_decay: _Optional[_Union[NumericDecayFunction, _Mapping]] = ..., weight: _Optional[float] = ...) -> None: ...
360362

361363
class PropertyValueFunction(_message.Message):
362364
__slots__ = ("property", "modifier")
@@ -366,7 +368,7 @@ class PropertyValueFunction(_message.Message):
366368
modifier: PropertyValueModifier
367369
def __init__(self, property: _Optional[str] = ..., modifier: _Optional[_Union[PropertyValueModifier, str]] = ...) -> None: ...
368370

369-
class DecayFunction(_message.Message):
371+
class TimeDecayFunction(_message.Message):
370372
__slots__ = ("property", "origin", "scale", "offset", "curve", "decay_value")
371373
PROPERTY_FIELD_NUMBER: _ClassVar[int]
372374
ORIGIN_FIELD_NUMBER: _ClassVar[int]
@@ -381,3 +383,19 @@ class DecayFunction(_message.Message):
381383
curve: DecayCurve
382384
decay_value: float
383385
def __init__(self, property: _Optional[str] = ..., origin: _Optional[str] = ..., scale: _Optional[str] = ..., offset: _Optional[str] = ..., curve: _Optional[_Union[DecayCurve, str]] = ..., decay_value: _Optional[float] = ...) -> None: ...
386+
387+
class NumericDecayFunction(_message.Message):
388+
__slots__ = ("property", "origin", "scale", "offset", "curve", "decay_value")
389+
PROPERTY_FIELD_NUMBER: _ClassVar[int]
390+
ORIGIN_FIELD_NUMBER: _ClassVar[int]
391+
SCALE_FIELD_NUMBER: _ClassVar[int]
392+
OFFSET_FIELD_NUMBER: _ClassVar[int]
393+
CURVE_FIELD_NUMBER: _ClassVar[int]
394+
DECAY_VALUE_FIELD_NUMBER: _ClassVar[int]
395+
property: str
396+
origin: float
397+
scale: float
398+
offset: float
399+
curve: DecayCurve
400+
decay_value: float
401+
def __init__(self, property: _Optional[str] = ..., origin: _Optional[float] = ..., scale: _Optional[float] = ..., offset: _Optional[float] = ..., curve: _Optional[_Union[DecayCurve, str]] = ..., decay_value: _Optional[float] = ...) -> None: ...

0 commit comments

Comments
 (0)