Skip to content

Commit 1c0cf33

Browse files
authored
Added README.md (#10)
* Added README.md * Fixed typo's
1 parent 73713b7 commit 1c0cf33

File tree

1 file changed

+280
-0
lines changed

1 file changed

+280
-0
lines changed

README.md

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
## Introduction ##
2+
3+
The Predis Vector Library (PredisVL) is a PHP client for AI applications leveraging Redis.
4+
5+
Designed for:
6+
- Vector similarity search
7+
- Recommendation engine
8+
9+
A perfect tool for Redis-based applications, incorporating capabilities like vector-based semantic search,
10+
full-text search, and geo-spatial search.
11+
12+
## Getting started ##
13+
14+
### Installation ###
15+
16+
For now PredisVL isn't available at packagist.org, but you can still install it via Composer by specifying [GitHub
17+
repository](https://github.com/vladvildanov/predis-vl) in your composer.json file.
18+
19+
```shell
20+
{
21+
"repositories": [
22+
{
23+
"type": "github",
24+
"url": "https://github.com/vladvildanov/predis-vl.git"
25+
}
26+
]
27+
}
28+
```
29+
```shell
30+
composer install vladvildanov/predis-vl
31+
```
32+
33+
### Setting up Redis ####
34+
35+
Choose from multiple Redis deployment options:
36+
1. [Redis Cloud](https://redis.com/try-free/): Managed cloud database (free tier available)
37+
2. [Redis Stack](https://redis.io/docs/install/install-stack/docker/): Docker image for development
38+
```shell
39+
docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
40+
```
41+
3. [Redis Enterprise](https://redis.com/redis-enterprise/advantages/): Commercial, self-hosted database
42+
43+
## What's included? ##
44+
45+
### Redis index management ###
46+
47+
1. Design your schema that models your dataset with one of the available Redis data structures (HASH, JSON)
48+
and indexable fields (e.g. text, tags, numerics, geo, and vectors).
49+
50+
Load schema as a dictionary:
51+
```php
52+
$schema = [
53+
'index' => [
54+
'name' => 'products',
55+
'prefix' => 'product:',
56+
'storage_type' => 'hash',
57+
],
58+
'fields' => [
59+
'id' => [
60+
'type' => 'numeric',
61+
],
62+
'categories' => [
63+
'type' => 'tag',
64+
],
65+
'description' => [
66+
'type' => 'text',
67+
],
68+
'description_embedding' => [
69+
'type' => 'vector',
70+
'dims' => 3,
71+
'datatype' => 'float32',
72+
'algorithm' => 'flat',
73+
'distance_metric' => 'cosine'
74+
],
75+
],
76+
];
77+
```
78+
2. Create a SearchIndex object with an input schema and client connection to be able to interact with your Redis index
79+
```php
80+
use Predis\Client;
81+
use Vladvildanov\PredisVl\Index\SearchIndex;
82+
83+
$client = new Client();
84+
$index = new SearchIndex($client, $schema);
85+
86+
// Creates index in the Redis
87+
$index->create();
88+
```
89+
3. Load/fetch your data from index. If you have a hash index data should be loaded as key-value pairs
90+
, for json type data loads as json string.
91+
```php
92+
$data = ['id' => '1', 'count' => 10, 'id_embeddings' => VectorHelper::toBytes([0.000001, 0.000002, 0.000003])];
93+
94+
// Loads given dataset associated with given key.
95+
$index->load('key', $data);
96+
97+
// Fetch dataset corresponding to given key
98+
$index->fetch('key');
99+
```
100+
101+
### Realtime search ###
102+
103+
Define queries and perform advanced search over your indices, including combination of vectors and variety of filters.
104+
105+
**VectorQuery** - flexible vector-similarity semantic search with customizable filters
106+
```php
107+
use Vladvildanov\PredisVl\Query\VectorQuery;
108+
109+
$query = new VectorQuery(
110+
[0.001, 0.002, 0.03],
111+
'description_embedding',
112+
null,
113+
3
114+
);
115+
116+
// Run vector search against vector field specified in schema.
117+
$results = $index->query($query);
118+
```
119+
120+
Incorporate complex metadata filters on your queries:
121+
```php
122+
use Vladvildanov\PredisVl\Query\Filter\TagFilter;
123+
use Vladvildanov\PredisVl\Enum\Condition;
124+
125+
$filter = new TagFilter(
126+
'categories',
127+
Condition::equal,
128+
'foo'
129+
);
130+
131+
$query = new VectorQuery(
132+
[0.001, 0.002, 0.03],
133+
'description_embedding',
134+
null,
135+
10,
136+
true,
137+
2,
138+
$filter
139+
);
140+
141+
// Results will be filtered by tag field values.
142+
$results = $index->query($query);
143+
```
144+
145+
### Filter types ###
146+
147+
#### Numeric ####
148+
149+
Numeric filters could be applied to numeric fields.
150+
Supports variety of conditions applicable for scalar types (==, !=, <, >, <=, >=).
151+
More information [here](https://redis.io/docs/interact/search-and-query/query/range/).
152+
```php
153+
use Vladvildanov\PredisVl\Query\Filter\NumericFilter;
154+
use Vladvildanov\PredisVl\Enum\Condition;
155+
156+
$equal = new NumericFilter('numeric', Condition::equal, 10);
157+
$notEqual = new NumericFilter('numeric', Condition::notEqual, 10);
158+
$greaterThan = new NumericFilter('numeric', Condition::greaterThan, 10);
159+
$greaterThanOrEqual = new NumericFilter('numeric', Condition::greaterThanOrEqual, 10);
160+
$lowerThan = new NumericFilter('numeric', Condition::lowerThan, 10);
161+
$lowerThanOrEqual = new NumericFilter('numeric', Condition::lowerThanOrEqual, 10);
162+
```
163+
164+
#### Tag ####
165+
166+
Tag filters could be applied to tag fields. Single or multiple values can be provided, single values supports only
167+
equality conditions (==, !==), for multiple tags additional conjunction (AND, OR) could be specified.
168+
More information [here](https://redis.io/docs/interact/search-and-query/advanced-concepts/tags/)
169+
```php
170+
use Vladvildanov\PredisVl\Query\Filter\TagFilter;
171+
use Vladvildanov\PredisVl\Enum\Condition;
172+
use Vladvildanov\PredisVl\Enum\Logical;
173+
174+
$singleTag = new TagFilter('tag', Condition::equal, 'value')
175+
$multipleTags = new TagFilter('tag', Condition::notEqual, [
176+
'conjunction' => Logical::or,
177+
'tags' => ['value1', 'value2']
178+
])
179+
```
180+
181+
#### Text ####
182+
183+
Text filters could be applied to text fields. Values can be provided as a single word or multiple words with
184+
specified condition. Empty value corresponds to all values (*).
185+
More information [here](https://redis.io/docs/interact/search-and-query/query/full-text/)
186+
```php
187+
use Vladvildanov\PredisVl\Query\Filter\TextFilter;
188+
use Vladvildanov\PredisVl\Enum\Condition;
189+
190+
$single = new TextFilter('text', Condition::equal, 'foo');
191+
192+
// Matching foo AND bar
193+
$multipleAnd = new TextFilter('text', Condition::equal, 'foo bar');
194+
195+
// Matching foo OR bar
196+
$multipleOr = new TextFilter('text', Condition::equal, 'foo|bar');
197+
198+
// Perform fuzzy search
199+
$fuzzy = new TextFilter('text', Condition::equal, '%foobaz%');
200+
```
201+
202+
#### Geo ####
203+
204+
Geo filters could be applied to geo fields. Supports only equality conditions,
205+
value should be specified as specific-shape array.
206+
More information [here](https://redis.io/docs/interact/search-and-query/query/geo-spatial/)
207+
```php
208+
use Vladvildanov\PredisVl\Query\Filter\GeoFilter;
209+
use Vladvildanov\PredisVl\Enum\Condition;
210+
use Vladvildanov\PredisVl\Enum\Unit;
211+
212+
$geo = new GeoFilter('geo', Condition::equal, [
213+
'lon' => 10.111,
214+
'lat' => 11.111,
215+
'radius' => 100,
216+
'unit' => Unit::kilometers
217+
]);
218+
```
219+
220+
#### Aggregate ####
221+
222+
To apply multiple filters to a single query use AggregateFilter.
223+
If there's the same logical operator that should be applied for each filter you can pass values in constructor,
224+
if you need a specific combination use `and()` and `or()` methods to create combined filter.
225+
```php
226+
use Vladvildanov\PredisVl\Query\Filter\AggregateFilter;
227+
use Vladvildanov\PredisVl\Query\Filter\TextFilter;
228+
use Vladvildanov\PredisVl\Query\Filter\NumericFilter;
229+
use Vladvildanov\PredisVl\Enum\Condition;
230+
use Vladvildanov\PredisVl\Enum\Logical;
231+
232+
$aggregate = new AggregateFilter([
233+
new TextFilter('text', Condition::equal, 'value'),
234+
new NumericFilter('numeric', Condition::greaterThan, 10)
235+
], Logical::or);
236+
237+
$combinedAggregate = new AggregateFilter();
238+
$combinedAggregate
239+
->and(
240+
new TextFilter('text', Condition::equal, 'value'),
241+
new NumericFilter('numeric', Condition::greaterThan, 10)
242+
)->or(
243+
new NumericFilter('numeric', Condition::lowerThan, 100)
244+
);
245+
```
246+
247+
## Vectorizers ##
248+
249+
To be able to effectively create vector representations for your indexed data or queries, you have to use
250+
[LLM's](https://en.wikipedia.org/wiki/Large_language_model). There's a variety of vectorizers that provide integration
251+
with popular embedding models.
252+
253+
The only required option is your API key specified as environment variable or configuration option.
254+
255+
### OpenAI ###
256+
```php
257+
use Vladvildanov\PredisVl\Vectorizer\Factory;
258+
259+
putenv('OPENAI_API_TOKEN=your_token');
260+
261+
$factory = new Factory();
262+
$vectorizer = $factory->createVectorizer('openai');
263+
264+
// Creates vector representation of given text.
265+
$embedding = $vectorizer->embed('your_text')
266+
267+
// Creates a single vector representation from multiple chunks.
268+
$mergedEmbedding = $vectorizer->batchEmbed(['first_chunk', 'second_chunk']);
269+
```
270+
271+
### VectorHelper ###
272+
273+
When you perform vector queries against Redis or load hash data into index that contains vector field data,
274+
your vector should be represented as a blob string. VectorHelper allows you to create
275+
blob representation from your vector represented as array of floats.
276+
```php
277+
use Vladvildanov\PredisVl\VectorHelper;
278+
279+
$blobVector = VectorHelper::toBytes([0.001, 0.002, 0.003]);
280+
```

0 commit comments

Comments
 (0)