Skip to content

Commit f925eac

Browse files
authored
Merge pull request #69 from dipinarora9/master - ADDHASH
feat: Added support for ADDHASH command
2 parents c54dd56 + 9106c12 commit f925eac

File tree

5 files changed

+214
-22
lines changed

5 files changed

+214
-22
lines changed

API.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,25 @@ Add a single document to the index.
195195
NOTE: Geo points shoule be encoded as strings of "lon,lat"
196196

197197

198+
### add\_document\_hash
199+
```py
200+
201+
def add_document_hash(self, doc_id, score=1.0, language=None, replace=False)
202+
203+
```
204+
205+
206+
207+
Add a hash document to the index.
208+
209+
### Parameters
210+
211+
- **doc_id**: the document's id. This has to be an existing HASH key in Redis that will hold the fields the index needs.
212+
- **score**: the document ranking, between 0.0 and 1.0
213+
- **replace**: if True, and the document already is in the index, we perform an update and reindex the document
214+
- **language**: Specify the language used for document tokenization.
215+
216+
198217
### aggregate
199218
```py
200219

@@ -264,7 +283,7 @@ Create the search index. The index must not already exist.
264283
### delete\_document
265284
```py
266285

267-
def delete_document(self, doc_id, conn=None)
286+
def delete_document(self, doc_id, conn=None, delete_actual_document=False)
268287

269288
```
270289

@@ -273,6 +292,9 @@ def delete_document(self, doc_id, conn=None)
273292
Delete a document from index
274293
Returns 1 if the document was deleted, 0 if not
275294

295+
### Parameters
296+
297+
- **delete_actual_document**: if set to True, RediSearch also delete the actual document if it is in the index
276298

277299
### drop\_index
278300
```py
@@ -361,6 +383,18 @@ def add_document(self, doc_id, nosave=False, score=1.0, payload=None, replace=Fa
361383
Add a document to the batch query
362384

363385

386+
### add\_document\_hash
387+
```py
388+
389+
def add_document_hash(self, doc_id, score=1.0, language=None, replace=False)
390+
391+
```
392+
393+
394+
395+
Add a hash document to the batch query
396+
397+
364398
### commit
365399
```py
366400

gendoc.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,4 @@ def generatedocs(module):
7171
print("Error while trying to import " + module)
7272

7373
if __name__ == '__main__':
74-
75-
print generatedocs(sys.argv[1])
74+
print(generatedocs(sys.argv[1]))

redisearch/client.py

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Field(object):
2626
def __init__(self, name, *args):
2727
self.name = name
2828
self.args = args
29-
29+
3030
def redis_args(self):
3131
return [self.name] + list(self.args)
3232

@@ -87,14 +87,15 @@ class TagField(Field):
8787
TagField is a tag-indexing field with simpler compression and tokenization.
8888
See http://redisearch.io/Tags/
8989
"""
90-
def __init__(self, name, separator = ',', no_index=False):
90+
91+
def __init__(self, name, separator=',', no_index=False):
9192
args = [Field.TAG, Field.SEPARATOR, separator]
9293

9394
if no_index:
9495
args.append(Field.NOINDEX)
9596

9697
Field.__init__(self, name, *args)
97-
98+
9899

99100
class Client(object):
100101
"""
@@ -108,6 +109,7 @@ class Client(object):
108109
ALTER_CMD = 'FT.ALTER'
109110
SEARCH_CMD = 'FT.SEARCH'
110111
ADD_CMD = 'FT.ADD'
112+
ADDHASH_CMD = "FT.ADDHASH"
111113
DROP_CMD = 'FT.DROP'
112114
EXPLAIN_CMD = 'FT.EXPLAIN'
113115
DEL_CMD = 'FT.DEL'
@@ -120,7 +122,6 @@ class Client(object):
120122
GET_CMD = 'FT.GET'
121123
MGET_CMD = 'FT.MGET'
122124

123-
124125
NOOFFSETS = 'NOOFFSETS'
125126
NOFIELDS = 'NOFIELDS'
126127
STOPWORDS = 'STOPWORDS'
@@ -156,6 +157,20 @@ def add_document(self, doc_id, nosave=False, score=1.0, payload=None,
156157
if self.current_chunk >= self.chunk_size:
157158
self.commit()
158159

160+
def add_document_hash(
161+
self, doc_id, score=1.0, replace=False,
162+
):
163+
"""
164+
Add a hash to the batch query
165+
"""
166+
self.client._add_document_hash(
167+
doc_id, conn=self.pipeline, score=score, replace=replace,
168+
)
169+
self.current_chunk += 1
170+
self.total += 1
171+
if self.current_chunk >= self.chunk_size:
172+
self.commit()
173+
159174
def commit(self):
160175
"""
161176
Manually commit and flush the batch indexing query
@@ -182,7 +197,7 @@ def batch_indexer(self, chunk_size=100):
182197
return Client.BatchIndexer(self, chunk_size=chunk_size)
183198

184199
def create_index(self, fields, no_term_offsets=False,
185-
no_field_flags=False, stopwords = None):
200+
no_field_flags=False, stopwords=None):
186201
"""
187202
Create the search index. The index must not already exist.
188203
@@ -203,7 +218,7 @@ def create_index(self, fields, no_term_offsets=False,
203218
args += [self.STOPWORDS, len(stopwords)]
204219
if len(stopwords) > 0:
205220
args += list(stopwords)
206-
221+
207222
args.append('SCHEMA')
208223

209224
args += list(itertools.chain(*(f.redis_args() for f in fields)))
@@ -230,7 +245,7 @@ def drop_index(self):
230245
Drop the index if it exists
231246
"""
232247
return self.redis.execute_command(self.DROP_CMD, self.index_name)
233-
248+
234249
def _add_document(self, doc_id, conn=None, nosave=False, score=1.0, payload=None,
235250
replace=False, partial=False, language=None, no_create=False, **fields):
236251
"""
@@ -260,6 +275,25 @@ def _add_document(self, doc_id, conn=None, nosave=False, score=1.0, payload=None
260275
args += list(itertools.chain(*fields.items()))
261276
return conn.execute_command(*args)
262277

278+
def _add_document_hash(
279+
self, doc_id, conn=None, score=1.0, language=None, replace=False,
280+
):
281+
"""
282+
Internal add_document_hash used for both batch and single doc indexing
283+
"""
284+
if conn is None:
285+
conn = self.redis
286+
287+
args = [self.ADDHASH_CMD, self.index_name, doc_id, score]
288+
289+
if replace:
290+
args.append("REPLACE")
291+
292+
if language:
293+
args += ["LANGUAGE", language]
294+
295+
return conn.execute_command(*args)
296+
263297
def add_document(self, doc_id, nosave=False, score=1.0, payload=None,
264298
replace=False, partial=False, language=None, no_create=False, **fields):
265299
"""
@@ -281,20 +315,44 @@ def add_document(self, doc_id, nosave=False, score=1.0, payload=None,
281315
- **fields** kwargs dictionary of the document fields to be saved and/or indexed.
282316
NOTE: Geo points shoule be encoded as strings of "lon,lat"
283317
"""
284-
return self._add_document(doc_id, conn=None, nosave=nosave, score=score,
318+
return self._add_document(doc_id, conn=None, nosave=nosave, score=score,
285319
payload=payload, replace=replace,
286-
partial=partial, language=language,
287-
no_create=no_create,**fields)
320+
partial=partial, language=language,
321+
no_create=no_create, **fields)
322+
323+
def add_document_hash(
324+
self, doc_id, score=1.0, language=None, replace=False,
325+
):
326+
"""
327+
Add a hash document to the index.
328+
329+
### Parameters
330+
331+
- **doc_id**: the document's id. This has to be an existing HASH key in Redis that will hold the fields the index needs.
332+
- **score**: the document ranking, between 0.0 and 1.0
333+
- **replace**: if True, and the document already is in the index, we perform an update and reindex the document
334+
- **language**: Specify the language used for document tokenization.
335+
"""
336+
return self._add_document_hash(
337+
doc_id, conn=None, score=score, language=language, replace=replace,
338+
)
288339

289-
def delete_document(self, doc_id, conn=None):
340+
def delete_document(self, doc_id, conn=None, delete_actual_document=False):
290341
"""
291342
Delete a document from index
292343
Returns 1 if the document was deleted, 0 if not
344+
345+
### Parameters
346+
347+
- **delete_actual_document**: if set to True, RediSearch also delete the actual document if it is in the index
293348
"""
349+
args = [self.DEL_CMD, self.index_name, doc_id]
294350
if conn is None:
295351
conn = self.redis
352+
if delete_actual_document:
353+
args.append('DD')
296354

297-
return conn.execute_command(self.DEL_CMD, self.index_name, doc_id)
355+
return conn.execute_command(*args)
298356

299357
def load_document(self, id):
300358
"""
@@ -315,12 +373,12 @@ def load_document(self, id):
315373
def get(self, *ids):
316374
"""
317375
Returns the full contents of multiple documents.
318-
376+
319377
### Parameters
320-
378+
321379
- **ids**: the ids of the saved documents.
322380
"""
323-
381+
324382
return self.redis.execute_command('FT.MGET', self.index_name, *ids)
325383

326384
def info(self):
@@ -386,7 +444,8 @@ def aggregate(self, query):
386444
elif isinstance(query, Cursor):
387445
has_schema = False
388446
has_cursor = True
389-
cmd = [self.CURSOR_CMD, 'READ', self.index_name] + query.build_args()
447+
cmd = [self.CURSOR_CMD, 'READ',
448+
self.index_name] + query.build_args()
390449
else:
391450
raise ValueError('Bad query', query)
392451

@@ -401,7 +460,7 @@ def aggregate(self, query):
401460
else:
402461
cursor = None
403462

404-
if query._with_schema:
463+
if isinstance(query, AggregateRequest) and query._with_schema:
405464
schema = raw[0]
406465
rows = raw[2:]
407466
else:

redisearch/reducers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class avg(FieldOnlyReducer):
5656
def __init__(self, field):
5757
super(avg, self).__init__(field)
5858

59+
5960
class tolist(FieldOnlyReducer):
6061
"""
6162
Returns all the matched properties in a list
@@ -65,6 +66,7 @@ class tolist(FieldOnlyReducer):
6566
def __init__(self, field):
6667
super(tolist, self).__init__(field)
6768

69+
6870
class count_distinct(FieldOnlyReducer):
6971
"""
7072
Calculate the number of distinct values contained in all the results in
@@ -82,7 +84,7 @@ class count_distinctish(FieldOnlyReducer):
8284
group for the given field. This uses a faster algorithm than
8385
`count_distinct` but is less accurate
8486
"""
85-
name = 'COUNT_DISTINCTISH'
87+
NAME = 'COUNT_DISTINCTISH'
8688

8789

8890
class quantile(Reducer):
@@ -101,7 +103,7 @@ class stddev(FieldOnlyReducer):
101103
"""
102104
Return the standard deviation for the values within the group
103105
"""
104-
name = 'STDDEV'
106+
NAME = 'STDDEV'
105107

106108
def __init__(self, field):
107109
super(stddev, self).__init__(field)

0 commit comments

Comments
 (0)