kiarina-lib-redisearch 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kiarina/lib/redisearch/__init__.py +35 -0
- kiarina/lib/redisearch/_async/__init__.py +0 -0
- kiarina/lib/redisearch/_async/client.py +181 -0
- kiarina/lib/redisearch/_async/registry.py +16 -0
- kiarina/lib/redisearch/_core/__init__.py +0 -0
- kiarina/lib/redisearch/_core/context.py +69 -0
- kiarina/lib/redisearch/_core/operations/__init__.py +0 -0
- kiarina/lib/redisearch/_core/operations/count.py +55 -0
- kiarina/lib/redisearch/_core/operations/create_index.py +52 -0
- kiarina/lib/redisearch/_core/operations/delete.py +43 -0
- kiarina/lib/redisearch/_core/operations/drop_index.py +59 -0
- kiarina/lib/redisearch/_core/operations/exists_index.py +56 -0
- kiarina/lib/redisearch/_core/operations/find.py +105 -0
- kiarina/lib/redisearch/_core/operations/get.py +61 -0
- kiarina/lib/redisearch/_core/operations/get_info.py +155 -0
- kiarina/lib/redisearch/_core/operations/get_key.py +8 -0
- kiarina/lib/redisearch/_core/operations/migrate_index.py +160 -0
- kiarina/lib/redisearch/_core/operations/reset_index.py +60 -0
- kiarina/lib/redisearch/_core/operations/search.py +111 -0
- kiarina/lib/redisearch/_core/operations/set.py +65 -0
- kiarina/lib/redisearch/_core/utils/__init__.py +0 -0
- kiarina/lib/redisearch/_core/utils/calc_score.py +35 -0
- kiarina/lib/redisearch/_core/utils/marshal_mappings.py +57 -0
- kiarina/lib/redisearch/_core/utils/parse_search_result.py +57 -0
- kiarina/lib/redisearch/_core/utils/unmarshal_mappings.py +57 -0
- kiarina/lib/redisearch/_core/views/__init__.py +0 -0
- kiarina/lib/redisearch/_core/views/document.py +25 -0
- kiarina/lib/redisearch/_core/views/info_result.py +24 -0
- kiarina/lib/redisearch/_core/views/search_result.py +31 -0
- kiarina/lib/redisearch/_sync/__init__.py +0 -0
- kiarina/lib/redisearch/_sync/client.py +179 -0
- kiarina/lib/redisearch/_sync/registry.py +16 -0
- kiarina/lib/redisearch/asyncio.py +33 -0
- kiarina/lib/redisearch/filter/__init__.py +61 -0
- kiarina/lib/redisearch/filter/_decorators.py +28 -0
- kiarina/lib/redisearch/filter/_enums.py +28 -0
- kiarina/lib/redisearch/filter/_field/__init__.py +5 -0
- kiarina/lib/redisearch/filter/_field/base.py +67 -0
- kiarina/lib/redisearch/filter/_field/numeric.py +178 -0
- kiarina/lib/redisearch/filter/_field/tag.py +142 -0
- kiarina/lib/redisearch/filter/_field/text.py +111 -0
- kiarina/lib/redisearch/filter/_model.py +93 -0
- kiarina/lib/redisearch/filter/_registry.py +153 -0
- kiarina/lib/redisearch/filter/_types.py +32 -0
- kiarina/lib/redisearch/filter/_utils.py +18 -0
- kiarina/lib/redisearch/py.typed +0 -0
- kiarina/lib/redisearch/schema/__init__.py +25 -0
- kiarina/lib/redisearch/schema/_field/__init__.py +0 -0
- kiarina/lib/redisearch/schema/_field/base.py +20 -0
- kiarina/lib/redisearch/schema/_field/numeric.py +33 -0
- kiarina/lib/redisearch/schema/_field/tag.py +46 -0
- kiarina/lib/redisearch/schema/_field/text.py +44 -0
- kiarina/lib/redisearch/schema/_field/vector/__init__.py +0 -0
- kiarina/lib/redisearch/schema/_field/vector/base.py +61 -0
- kiarina/lib/redisearch/schema/_field/vector/flat.py +40 -0
- kiarina/lib/redisearch/schema/_field/vector/hnsw.py +53 -0
- kiarina/lib/redisearch/schema/_model.py +98 -0
- kiarina/lib/redisearch/schema/_types.py +16 -0
- kiarina/lib/redisearch/settings.py +47 -0
- kiarina_lib_redisearch-1.0.0.dist-info/METADATA +886 -0
- kiarina_lib_redisearch-1.0.0.dist-info/RECORD +62 -0
- kiarina_lib_redisearch-1.0.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
from typing import Any, TypeAlias
|
2
|
+
|
3
|
+
RedisearchFilterConditions: TypeAlias = list[list[Any]]
|
4
|
+
"""
|
5
|
+
RedisearchFilter に変換可能なリスト
|
6
|
+
|
7
|
+
Examples:
|
8
|
+
>>> [
|
9
|
+
... ["color", "in", ["blue", "red"]],
|
10
|
+
... ["price", "<", 1000],
|
11
|
+
... ["title", "like", "*hello*"]
|
12
|
+
... ]
|
13
|
+
|
14
|
+
Tag conditions:
|
15
|
+
- ["color", "==", "blue"]
|
16
|
+
- ["color", "!=", "blue"]
|
17
|
+
- ["color", "in", ["blue", "red"]]
|
18
|
+
- ["color", "not in", ["blue", "red"]]
|
19
|
+
|
20
|
+
Numeric conditions:
|
21
|
+
- ["price", "==", 1000]
|
22
|
+
- ["price", "!=", 1000]
|
23
|
+
- ["price", ">", 1000]
|
24
|
+
- ["price", "<", 1000]
|
25
|
+
- ["price", ">=", 1000]
|
26
|
+
- ["price", "<=", 1000]
|
27
|
+
|
28
|
+
Text conditions:
|
29
|
+
- ["title", "==", "hello"]
|
30
|
+
- ["title", "!=", "hello"]
|
31
|
+
- ["title", "like", "*hello*"]
|
32
|
+
"""
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
ESCAPED_CHARACTERS: str = r"[,.<>{}\[\]\\\"\':;!@#$%^&*()\-+=~\/ ]"
|
4
|
+
"""
|
5
|
+
Regular expression patterns
|
6
|
+
|
7
|
+
for characters requiring escaping in Redisearch queries
|
8
|
+
"""
|
9
|
+
|
10
|
+
ESCAPED_CHARACTERS_RE: re.Pattern[str] = re.compile(ESCAPED_CHARACTERS)
|
11
|
+
"""Compiled regular expression for escaped characters"""
|
12
|
+
|
13
|
+
|
14
|
+
def escape_token(value: str) -> str:
|
15
|
+
"""
|
16
|
+
Escape special characters in a Redisearch query token.
|
17
|
+
"""
|
18
|
+
return ESCAPED_CHARACTERS_RE.sub(r"\\\g<0>", value)
|
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
"""
|
2
|
+
フィールド名に `payload`, `distance` は使用できません。
|
3
|
+
フィールド名に `id` を使用する場合、ドキュメントの ID と同じ値として扱われます。
|
4
|
+
"""
|
5
|
+
|
6
|
+
from ._field.numeric import NumericFieldSchema
|
7
|
+
from ._field.tag import TagFieldSchema
|
8
|
+
from ._field.text import TextFieldSchema
|
9
|
+
from ._field.vector.flat import FlatVectorFieldSchema
|
10
|
+
from ._field.vector.hnsw import HNSWVectorFieldSchema
|
11
|
+
from ._model import RedisearchSchema
|
12
|
+
from ._types import FieldSchema
|
13
|
+
|
14
|
+
__all__ = [
|
15
|
+
# ._field
|
16
|
+
"FlatVectorFieldSchema",
|
17
|
+
"HNSWVectorFieldSchema",
|
18
|
+
"NumericFieldSchema",
|
19
|
+
"TagFieldSchema",
|
20
|
+
"TextFieldSchema",
|
21
|
+
# ._model
|
22
|
+
"RedisearchSchema",
|
23
|
+
# ._types
|
24
|
+
"FieldSchema",
|
25
|
+
]
|
File without changes
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from pydantic import BaseModel, Field, field_validator
|
2
|
+
|
3
|
+
|
4
|
+
class BaseFieldSchema(BaseModel):
|
5
|
+
"""
|
6
|
+
Base class of the field schema
|
7
|
+
"""
|
8
|
+
|
9
|
+
name: str = Field(...)
|
10
|
+
"""Redisearch field name"""
|
11
|
+
|
12
|
+
@field_validator("name")
|
13
|
+
@classmethod
|
14
|
+
def forbid_reserved_names(cls, v: str) -> str:
|
15
|
+
reserved = {"payload", "distance"}
|
16
|
+
|
17
|
+
if v in reserved:
|
18
|
+
raise ValueError(f'"{v}" is a reserved name and cannot be used.')
|
19
|
+
|
20
|
+
return v
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from typing import Literal
|
2
|
+
|
3
|
+
from redis.commands.search.field import NumericField
|
4
|
+
|
5
|
+
from .base import BaseFieldSchema
|
6
|
+
|
7
|
+
|
8
|
+
class NumericFieldSchema(BaseFieldSchema):
|
9
|
+
"""
|
10
|
+
Schema for numeric fields
|
11
|
+
"""
|
12
|
+
|
13
|
+
type: Literal["numeric"] = "numeric"
|
14
|
+
|
15
|
+
no_index: bool = False
|
16
|
+
"""Flag to prevent index creation"""
|
17
|
+
|
18
|
+
sortable: bool | None = False
|
19
|
+
"""Flag to indicate if the field is sortable"""
|
20
|
+
|
21
|
+
# --------------------------------------------------
|
22
|
+
# Public Methods
|
23
|
+
# --------------------------------------------------
|
24
|
+
|
25
|
+
def to_field(self) -> NumericField:
|
26
|
+
"""
|
27
|
+
Convert the field schema to a Redisearch field
|
28
|
+
"""
|
29
|
+
return NumericField(
|
30
|
+
self.name,
|
31
|
+
sortable=self.sortable,
|
32
|
+
no_index=self.no_index,
|
33
|
+
)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
from typing import Literal
|
2
|
+
|
3
|
+
from pydantic import Field
|
4
|
+
from redis.commands.search.field import TagField
|
5
|
+
|
6
|
+
from .base import BaseFieldSchema
|
7
|
+
|
8
|
+
|
9
|
+
class TagFieldSchema(BaseFieldSchema):
|
10
|
+
"""
|
11
|
+
Schema for tag fields
|
12
|
+
"""
|
13
|
+
|
14
|
+
type: Literal["tag"] = "tag"
|
15
|
+
|
16
|
+
separator: str = ","
|
17
|
+
"""Tag separator"""
|
18
|
+
|
19
|
+
case_sensitive: bool = False
|
20
|
+
"""Flag to indicate if case sensitivity is enabled"""
|
21
|
+
|
22
|
+
no_index: bool = False
|
23
|
+
"""Flag to prevent index creation"""
|
24
|
+
|
25
|
+
sortable: bool | None = False
|
26
|
+
"""Flag to indicate if the field is sortable"""
|
27
|
+
|
28
|
+
multiple: bool = Field(False, exclude=True)
|
29
|
+
"""
|
30
|
+
Flag to indicate if multiple tags are allowed
|
31
|
+
|
32
|
+
This field is not a feature of Redisearch and is only used within this library.
|
33
|
+
Therefore, it does not affect the migration.
|
34
|
+
"""
|
35
|
+
|
36
|
+
def to_field(self) -> TagField:
|
37
|
+
"""
|
38
|
+
Convert the field schema to a Redisearch field
|
39
|
+
"""
|
40
|
+
return TagField(
|
41
|
+
self.name,
|
42
|
+
separator=self.separator,
|
43
|
+
case_sensitive=self.case_sensitive,
|
44
|
+
sortable=self.sortable,
|
45
|
+
no_index=self.no_index,
|
46
|
+
)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from typing import Literal
|
2
|
+
|
3
|
+
from redis.commands.search.field import TextField
|
4
|
+
|
5
|
+
from .base import BaseFieldSchema
|
6
|
+
|
7
|
+
|
8
|
+
class TextFieldSchema(BaseFieldSchema):
|
9
|
+
"""
|
10
|
+
Schema for text fields
|
11
|
+
"""
|
12
|
+
|
13
|
+
type: Literal["text"] = "text"
|
14
|
+
|
15
|
+
weight: float = 1
|
16
|
+
"""Weight"""
|
17
|
+
|
18
|
+
no_stem: bool = False
|
19
|
+
"""Flag to indicate if stemming is disabled"""
|
20
|
+
|
21
|
+
phonetic_matcher: str | None = None
|
22
|
+
"""Phonetic matcher"""
|
23
|
+
|
24
|
+
withsuffixtrie: bool = False
|
25
|
+
"""Flag to indicate if suffix trie is used"""
|
26
|
+
|
27
|
+
no_index: bool = False
|
28
|
+
"""Flag to prevent index creation"""
|
29
|
+
|
30
|
+
sortable: bool | None = False
|
31
|
+
"""Flag to indicate if the field is sortable"""
|
32
|
+
|
33
|
+
def to_field(self) -> TextField:
|
34
|
+
"""
|
35
|
+
Convert the field schema to a Redisearch field
|
36
|
+
"""
|
37
|
+
return TextField(
|
38
|
+
self.name,
|
39
|
+
weight=self.weight,
|
40
|
+
no_stem=self.no_stem,
|
41
|
+
phonetic_matcher=self.phonetic_matcher, # type: ignore
|
42
|
+
sortable=self.sortable,
|
43
|
+
no_index=self.no_index,
|
44
|
+
)
|
File without changes
|
@@ -0,0 +1,61 @@
|
|
1
|
+
from typing import Any, Literal
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
from pydantic import Field
|
5
|
+
|
6
|
+
from ..base import BaseFieldSchema
|
7
|
+
|
8
|
+
|
9
|
+
class VectorFieldSchema(BaseFieldSchema):
|
10
|
+
"""
|
11
|
+
Base class for vector field schemas
|
12
|
+
"""
|
13
|
+
|
14
|
+
type: Literal["vector"] = "vector"
|
15
|
+
|
16
|
+
dims: int = Field(...)
|
17
|
+
"""Dimensionality"""
|
18
|
+
|
19
|
+
datatype: Literal["FLOAT32", "FLOAT64"] = "FLOAT32"
|
20
|
+
"""Data type"""
|
21
|
+
|
22
|
+
distance_metric: Literal["L2", "COSINE", "IP"] = "COSINE"
|
23
|
+
"""Distance metric"""
|
24
|
+
|
25
|
+
initial_cap: int | None = None
|
26
|
+
"""Initial capacity"""
|
27
|
+
|
28
|
+
# --------------------------------------------------
|
29
|
+
# Properties
|
30
|
+
# --------------------------------------------------
|
31
|
+
|
32
|
+
@property
|
33
|
+
def dtype(self) -> Any:
|
34
|
+
"""
|
35
|
+
Get the numpy data type
|
36
|
+
"""
|
37
|
+
if self.datatype == "FLOAT32":
|
38
|
+
return np.float32
|
39
|
+
elif self.datatype == "FLOAT64":
|
40
|
+
return np.float64
|
41
|
+
else:
|
42
|
+
raise ValueError(f"Unsupported datatype: {self.datatype}")
|
43
|
+
|
44
|
+
# --------------------------------------------------
|
45
|
+
# Protected Methods
|
46
|
+
# --------------------------------------------------
|
47
|
+
|
48
|
+
def _get_attributes(self) -> dict[str, Any]:
|
49
|
+
"""
|
50
|
+
Get attributes for the vector field
|
51
|
+
"""
|
52
|
+
attributes = {
|
53
|
+
"TYPE": self.datatype,
|
54
|
+
"DIM": self.dims,
|
55
|
+
"DISTANCE_METRIC": self.distance_metric,
|
56
|
+
}
|
57
|
+
|
58
|
+
if self.initial_cap is not None:
|
59
|
+
attributes["INITIAL_CAP"] = self.initial_cap
|
60
|
+
|
61
|
+
return attributes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from typing import Any, Literal
|
2
|
+
|
3
|
+
from redis.commands.search.field import VectorField
|
4
|
+
|
5
|
+
from .base import VectorFieldSchema
|
6
|
+
|
7
|
+
|
8
|
+
class FlatVectorFieldSchema(VectorFieldSchema):
|
9
|
+
"""
|
10
|
+
Schema for FLAT vector fields
|
11
|
+
"""
|
12
|
+
|
13
|
+
algorithm: Literal["FLAT"] = "FLAT"
|
14
|
+
|
15
|
+
block_size: int | None = None
|
16
|
+
|
17
|
+
# --------------------------------------------------
|
18
|
+
# Public Methods
|
19
|
+
# --------------------------------------------------
|
20
|
+
|
21
|
+
def to_field(self) -> VectorField:
|
22
|
+
"""
|
23
|
+
Convert field schema to Redisearch field
|
24
|
+
"""
|
25
|
+
return VectorField(self.name, self.algorithm, self._get_attributes())
|
26
|
+
|
27
|
+
# --------------------------------------------------
|
28
|
+
# Protected Methods
|
29
|
+
# --------------------------------------------------
|
30
|
+
|
31
|
+
def _get_attributes(self) -> dict[str, Any]:
|
32
|
+
"""
|
33
|
+
Get attributes for the vector field
|
34
|
+
"""
|
35
|
+
attributes = super()._get_attributes()
|
36
|
+
|
37
|
+
if self.block_size is not None:
|
38
|
+
attributes["BLOCK_SIZE"] = self.block_size
|
39
|
+
|
40
|
+
return attributes
|
@@ -0,0 +1,53 @@
|
|
1
|
+
from typing import Any, Literal
|
2
|
+
|
3
|
+
from pydantic import Field
|
4
|
+
from redis.commands.search.field import VectorField
|
5
|
+
|
6
|
+
from .base import VectorFieldSchema
|
7
|
+
|
8
|
+
|
9
|
+
class HNSWVectorFieldSchema(VectorFieldSchema):
|
10
|
+
"""
|
11
|
+
Schema for HNSW vector fields
|
12
|
+
"""
|
13
|
+
|
14
|
+
algorithm: Literal["HNSW"] = "HNSW"
|
15
|
+
|
16
|
+
m: int = Field(default=16)
|
17
|
+
|
18
|
+
ef_construction: int = Field(default=200)
|
19
|
+
|
20
|
+
ef_runtime: int = Field(default=10)
|
21
|
+
|
22
|
+
epsilon: float = Field(default=0.01)
|
23
|
+
|
24
|
+
# --------------------------------------------------
|
25
|
+
# Public Methods
|
26
|
+
# --------------------------------------------------
|
27
|
+
|
28
|
+
def to_field(self) -> VectorField:
|
29
|
+
"""
|
30
|
+
Convert field schema to Redisearch field
|
31
|
+
"""
|
32
|
+
return VectorField(self.name, self.algorithm, self._get_attributes())
|
33
|
+
|
34
|
+
# --------------------------------------------------
|
35
|
+
# Protected Methods
|
36
|
+
# --------------------------------------------------
|
37
|
+
|
38
|
+
def _get_attributes(self) -> dict[str, Any]:
|
39
|
+
"""
|
40
|
+
Get attributes for the vector field
|
41
|
+
"""
|
42
|
+
attributes = super()._get_attributes()
|
43
|
+
|
44
|
+
attributes.update(
|
45
|
+
{
|
46
|
+
"M": self.m,
|
47
|
+
"EF_CONSTRUCTION": self.ef_construction,
|
48
|
+
"EF_RUNTIME": self.ef_runtime,
|
49
|
+
"EPSILON": self.epsilon,
|
50
|
+
}
|
51
|
+
)
|
52
|
+
|
53
|
+
return attributes
|
@@ -0,0 +1,98 @@
|
|
1
|
+
from typing import Any, Self
|
2
|
+
|
3
|
+
from pydantic import BaseModel
|
4
|
+
from pydantic import Field as PydanticField
|
5
|
+
from redis.commands.search.field import Field as RedisearchField
|
6
|
+
|
7
|
+
from ._field.vector.flat import FlatVectorFieldSchema
|
8
|
+
from ._field.vector.hnsw import HNSWVectorFieldSchema
|
9
|
+
from ._types import FieldSchema
|
10
|
+
|
11
|
+
|
12
|
+
class RedisearchSchema(BaseModel):
|
13
|
+
"""
|
14
|
+
Redisearch index schema
|
15
|
+
"""
|
16
|
+
|
17
|
+
fields: list[FieldSchema] = PydanticField(default_factory=list)
|
18
|
+
"""All fields"""
|
19
|
+
|
20
|
+
# --------------------------------------------------
|
21
|
+
# Properties
|
22
|
+
# --------------------------------------------------
|
23
|
+
|
24
|
+
@property
|
25
|
+
def field_names(self) -> list[str]:
|
26
|
+
"""
|
27
|
+
Obtain the names of all fields in the schema
|
28
|
+
"""
|
29
|
+
return [field.name for field in self.fields if field.name]
|
30
|
+
|
31
|
+
@property
|
32
|
+
def vector_field(self) -> FlatVectorFieldSchema | HNSWVectorFieldSchema:
|
33
|
+
"""
|
34
|
+
Obtain the vector field from the schema
|
35
|
+
|
36
|
+
Even if there are two or more vector fields, the first one is returned.
|
37
|
+
The vector field used for vector search is assumed to exist only once,
|
38
|
+
if at all, within the schema.
|
39
|
+
"""
|
40
|
+
for field in self.fields:
|
41
|
+
if field.type == "vector":
|
42
|
+
return field
|
43
|
+
|
44
|
+
raise ValueError("No vector field found")
|
45
|
+
|
46
|
+
# --------------------------------------------------
|
47
|
+
# Magic Methods
|
48
|
+
# --------------------------------------------------
|
49
|
+
|
50
|
+
def __eq__(self, other: Any) -> bool:
|
51
|
+
if not isinstance(other, RedisearchSchema):
|
52
|
+
return False
|
53
|
+
|
54
|
+
# Ignore fields not output by model_dump() when comparing
|
55
|
+
return self.model_dump() == other.model_dump()
|
56
|
+
|
57
|
+
# --------------------------------------------------
|
58
|
+
# Public Methods
|
59
|
+
# --------------------------------------------------
|
60
|
+
|
61
|
+
def get_field(self, name: str) -> FieldSchema | None:
|
62
|
+
"""
|
63
|
+
Get a field by its name
|
64
|
+
|
65
|
+
Args:
|
66
|
+
name (str): Field name
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
FieldSchema | None: The field if found, otherwise None
|
70
|
+
"""
|
71
|
+
for field in self.fields:
|
72
|
+
if field.name == name:
|
73
|
+
return field
|
74
|
+
|
75
|
+
return None
|
76
|
+
|
77
|
+
def to_fields(self) -> list[RedisearchField]:
|
78
|
+
"""
|
79
|
+
Convert the schema model to a list of Redisearch fields
|
80
|
+
"""
|
81
|
+
return [field.to_field() for field in self.fields]
|
82
|
+
|
83
|
+
# --------------------------------------------------
|
84
|
+
# Class Methods
|
85
|
+
# --------------------------------------------------
|
86
|
+
|
87
|
+
@classmethod
|
88
|
+
def from_field_dicts(cls, field_dicts: list[dict[str, Any]]) -> Self:
|
89
|
+
"""
|
90
|
+
Create a schema model from a list of field dictionaries
|
91
|
+
|
92
|
+
Args:
|
93
|
+
field_dicts (list[dict[str, Any]]): List of field dictionaries
|
94
|
+
|
95
|
+
Returns:
|
96
|
+
RedisearchSchema: The schema model
|
97
|
+
"""
|
98
|
+
return cls.model_validate({"fields": field_dicts})
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from typing import TypeAlias
|
2
|
+
|
3
|
+
from ._field.numeric import NumericFieldSchema
|
4
|
+
from ._field.tag import TagFieldSchema
|
5
|
+
from ._field.text import TextFieldSchema
|
6
|
+
from ._field.vector.flat import FlatVectorFieldSchema
|
7
|
+
from ._field.vector.hnsw import HNSWVectorFieldSchema
|
8
|
+
|
9
|
+
FieldSchema: TypeAlias = (
|
10
|
+
NumericFieldSchema
|
11
|
+
| TagFieldSchema
|
12
|
+
| TextFieldSchema
|
13
|
+
| FlatVectorFieldSchema
|
14
|
+
| HNSWVectorFieldSchema
|
15
|
+
)
|
16
|
+
"""Type of the field schema"""
|
@@ -0,0 +1,47 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
4
|
+
from pydantic_settings_manager import SettingsManager
|
5
|
+
|
6
|
+
|
7
|
+
class RedisearchSettings(BaseSettings):
|
8
|
+
"""
|
9
|
+
Redisearch settings
|
10
|
+
"""
|
11
|
+
|
12
|
+
model_config = SettingsConfigDict(env_prefix="KIARINA_LIB_REDISEARCH_")
|
13
|
+
|
14
|
+
key_prefix: str = ""
|
15
|
+
"""
|
16
|
+
Redis key prefix
|
17
|
+
|
18
|
+
The prefix for keys of documents registered with Redisearch.
|
19
|
+
Specify a string ending with a colon. e.g. "myapp:"
|
20
|
+
"""
|
21
|
+
|
22
|
+
index_name: str = "default"
|
23
|
+
"""
|
24
|
+
Redisearch index name
|
25
|
+
|
26
|
+
Only alphanumeric characters, underscores, hyphens, and periods.
|
27
|
+
The beginning consists solely of letters.
|
28
|
+
"""
|
29
|
+
|
30
|
+
index_schema: list[dict[str, Any]] | None = None
|
31
|
+
"""
|
32
|
+
Redisearch index schema
|
33
|
+
|
34
|
+
RedisearchSchema.from_field_dicts can be used to
|
35
|
+
create the schema from a list of field dictionaries.
|
36
|
+
"""
|
37
|
+
|
38
|
+
protect_index_deletion: bool = False
|
39
|
+
"""
|
40
|
+
Protect index deletion
|
41
|
+
|
42
|
+
When set to True, the delete_index operation is protected,
|
43
|
+
preventing the index from being accidentally deleted.
|
44
|
+
"""
|
45
|
+
|
46
|
+
|
47
|
+
settings_manager = SettingsManager(RedisearchSettings, multi=True)
|