Skip to content

Commit

Permalink
Adds Search module and create_index command in python
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamazon committed Jan 31, 2024
1 parent 96adb91 commit 53899f2
Show file tree
Hide file tree
Showing 10 changed files with 849 additions and 20 deletions.
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ enum RequestType {
Zcard = 64;
Zcount = 65;
ZIncrBy = 66;
FTCreateIndex=67;
}

message Command {
Expand Down
1 change: 1 addition & 0 deletions glide-core/src/socket_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ fn get_command(request: &Command) -> Option<Cmd> {
RequestType::Zcard => Some(cmd("ZCARD")),
RequestType::Zcount => Some(cmd("ZCOUNT")),
RequestType::ZIncrBy => Some(cmd("ZINCRBY")),
RequestType::FTCreateIndex => Some(cmd("FT.CREATE")),
}
}

Expand Down
3 changes: 2 additions & 1 deletion python/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[pytest]
markers =
smoke_test: mark a test as a build verification testing.
addopts = -k "not test_redis_modules.py"
# Disabaling module tests by default
addopts = -k "not test_search.py"
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0

from .commands import Search
from .field import (
CoordinateSystem,
GeoField,
GeoShapeField,
NumericField,
PhoneticType,
SortableOption,
TagField,
TextField,
VectorAlgorithm,
VectorField,
)
from .index import Index, IndexType
from .optional_params import FieldFlag, Frequencies, Highlights, InitialScan, Offset

__all__ = [
"CoordinateSystem",
"FieldFlag",
"Frequencies",
"GeoField",
"GeoShapeField",
"Highlights",
"Index",
"IndexType",
"InitialScan",
"NumericField",
"Offset",
"PhoneticType",
"Search",
"SortableOption",
"TagField",
"TextField",
"VectorAlgorithm",
"VectorField",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0

from typing import List, Optional, cast

from glide.async_commands.redis_modules.search.optional_params import (
FieldFlag,
Frequencies,
Highlights,
InitialScan,
Offset,
)
from glide.constants import TOK
from glide.protobuf.redis_request_pb2 import RequestType
from glide.redis_client import TRedisClient

from .field import Field
from .index import Index


class Search:
"""Class for RediSearch commands."""

async def create_index(
self,
client: TRedisClient,
index: Index,
schema: List[Field],
max_text_fields: bool = False,
temporary_seconds: Optional[int] = None,
offset: Offset = Offset.STORE_OFFSET,
highlight: Highlights = Highlights.USE_HIGHLIGHTS,
field_flag: FieldFlag = FieldFlag.USE_FIELDS,
frequencies: Frequencies = Frequencies.SAVE_FREQUENCIES,
stop_words: Optional[List[str]] = None,
initial_scan: InitialScan = InitialScan.SCAN_INDEX,
) -> TOK:
"""
Creates a new search index with the specified configuration.
See https://redis.io/commands/ft.create/ for more details.
Args:
client (TRedisClient): The Redis client to execute the command.
index (Index): The definition of the index, including its name and type.
schema (List[Field]): The schema of the index, specifying the fields and their types.
max_text_fields (bool): Forces to encode indexes as if there were more than 32 text attributes.
Additional attributes (beyond 32) can be added using the module's alter command
temporary_seconds (Optional[int]): Creates a lightweight temporary index that automatically expires after a set period of inactivity, measured in seconds.
The index's internal idle timer resets each time a search or addition operation occurs.
Because such indexes are lightweight, you can create thousands of such indexes without negative performance implications and, therefore,
you should consider setting `initial_scan` to be InitialScan.SKIP_SCAN to avoid costly scanning.
Warning: When temporary indexes expire, they drop all the records associated with them.
offset (Offset): Whether to store term offsets for documents.
highlight (Highlights): Whether to disable / enable highlighting support.
field_flag (FieldFlag): Whether to store attribute bits for each term.
frequencies (Frequencies): Whether to save the term frequencies in the index.
stop_words (Optional[List[str]]): Sets the index with a custom stopword list, to be ignored during indexing and search time.
If not set, the module defaults to using its predefined list of stopwords. If an empty list is provided, the index will have no stopwords.
initial_scan (InitialScan): Whether to scan and index.
Returns:
A simple OK response.
Examples:
>>> index = Index("my_index", IndexType.HASH)
>>> schema = [TextField("name"), NumericField("age")]
>>> await search_commands.create_index(
redis_client,
index,
schema,
max_text_fields=True,
temporary_seconds=3600,
field_flags=FieldFlags.NO_FIELDS,
stopwords=["the", "and", "is"]
)
"OK"
"""
args = index.get_index_atr()
if max_text_fields:
args.append("MAXTEXTFIELDS")
if temporary_seconds is not None:
args.extend(["TEMPORARY", str(temporary_seconds)])
if offset == Offset.NO_OFFSET:
args.append("NOOFFSETS")
if highlight == Highlights.NO_HIGHLIGHTS:
args.append("NOHL")
if field_flag == FieldFlag.NO_FIELDS:
args.append("NOFIELDS")
if frequencies == Frequencies.NO_FREQUENCIES:
args.append("NOFREQS")
if stop_words is not None:
args.extend(["STOPWORDS", str(len(stop_words)), *stop_words])
if initial_scan == InitialScan.SKIP_SCAN:
args.append("SKIPINITIALSCAN")
args.append("SCHEMA")
for field in schema:
args.extend(field.get_field_args())

return cast(TOK, await client._execute_command(RequestType.FTCreateIndex, args))
Loading

0 comments on commit 53899f2

Please sign in to comment.