diff --git a/redisearch/client.py b/redisearch/client.py
index f19c041..023504a 100644
--- a/redisearch/client.py
+++ b/redisearch/client.py
@@ -107,7 +107,8 @@ class IndexDefinition(object):
IndexDefinition is used to define a index definition for automatic indexing on Hash or Json update.
"""
- def __init__(self, prefix=[], filter=None, language_field=None, language=None, score_field=None, score=1.0, payload_field=None, index_type=None):
+ def __init__(self, prefix=[], filter=None, language_field=None, language=None, score_field=None,
+ score=1.0, payload_field=None, index_type=None):
args = []
if index_type is IndexType.HASH:
@@ -182,7 +183,12 @@ class Client(object):
NOOFFSETS = 'NOOFFSETS'
NOFIELDS = 'NOFIELDS'
+ NOHL = 'NOHL'
+ NOFREQS = 'NOFREQS'
+ MAXTEXTFIELDS = 'MAXTEXTFIELDS'
+ TEMPORARY = 'TEMPORARY'
STOPWORDS = 'STOPWORDS'
+ SKIPINITIALSCAN = 'SKIPINITIALSCAN'
class BatchIndexer(object):
"""
@@ -256,7 +262,9 @@ def batch_indexer(self, chunk_size=100):
return Client.BatchIndexer(self, chunk_size=chunk_size)
def create_index(self, fields, no_term_offsets=False,
- no_field_flags=False, stopwords=None, definition=None):
+ no_field_flags=False, stopwords=None, definition=None,
+ max_text_fields=False, temporary=None, no_highlight=False,
+ no_term_frequencies=False, skip_initial_scan=False):
"""
Create the search index. The index must not already exist.
@@ -266,15 +274,33 @@ def create_index(self, fields, no_term_offsets=False,
- **no_term_offsets**: If true, we will not save term offsets in the index
- **no_field_flags**: If true, we will not save field flags that allow searching in specific fields
- **stopwords**: If not None, we create the index with this custom stopword list. The list can be empty
+ - **max_text_fields**: If true, we will encode indexes as if there were more than 32 text fields,
+ which allows you to add additional fields (beyond 32).
+ - **temporary**: Create a lightweight temporary index which will expire after the specified period of
+ inactivity (in seconds). The internal idle timer is reset whenever the index is searched or added to.
+ - **no_highlight**: If true, disabling highlighting support. Also implied by no_term_offsets.
+ - **no_term_frequencies**: If true, we avoid saving the term frequencies in the index.
+ - **skip_initial_scan**: If true, we do not scan and index.
"""
args = [self.CREATE_CMD, self.index_name]
if definition is not None:
- args += definition.args
+ args += definition.args
+ if max_text_fields:
+ args.append(self.MAXTEXTFIELDS)
+ if temporary is not None and isinstance(temporary, int):
+ args.append(self.TEMPORARY)
+ args.append(temporary)
if no_term_offsets:
args.append(self.NOOFFSETS)
+ if no_highlight:
+ args.append(self.NOHL)
if no_field_flags:
args.append(self.NOFIELDS)
+ if no_term_frequencies:
+ args.append(self.NOFREQS)
+ if skip_initial_scan:
+ args.append(self.SKIPINITIALSCAN)
if stopwords is not None and isinstance(stopwords, (list, tuple, set)):
args += [self.STOPWORDS, len(stopwords)]
if len(stopwords) > 0:
diff --git a/test/test.py b/test/test.py
index b7aeb7d..22142cd 100644
--- a/test/test.py
+++ b/test/test.py
@@ -300,6 +300,28 @@ def testReplace(self):
self.assertEqual(1, res.total)
self.assertEqual('doc1', res.docs[0].id)
+ def testExpire(self):
+ client = self.getCleanClient('idx')
+ client.create_index((TextField('txt', sortable=True),), temporary=4)
+
+ redis_client = redis.client.Redis()
+ ttl = redis_client.execute_command('ft.debug', 'TTL', 'idx')
+ self.assertTrue(ttl > 2)
+ while ttl > 2:
+ ttl = redis_client.execute_command('ft.debug', 'TTL', 'idx')
+ time.sleep(0.01)
+
+ # add document - should reset the ttl
+ client.add_document('doc', txt='foo bar', text='this is a simple test')
+ ttl = redis_client.execute_command('ft.debug', 'TTL', 'idx')
+ self.assertTrue(ttl > 2)
+ try:
+ while True:
+ ttl = redis_client.execute_command('ft.debug', 'TTL', 'idx')
+ time.sleep(0.5)
+ except redis.exceptions.ResponseError:
+ self.assertEqual(ttl, 0)
+
def testStopwords(self):
# Creating a client with a given index name
client = self.getCleanClient('idx')
@@ -314,6 +336,18 @@ def testStopwords(self):
self.assertEqual(0, res1.total)
self.assertEqual(1, res2.total)
+ def testSkipInitialScan(self):
+ client = self.getCleanClient('idx')
+ client.redis.hset("doc1", "foo", "bar")
+ q = Query('@foo:bar')
+
+ client1 = self.getCleanClient('idx1')
+ client1.create_index((TextField('foo'),))
+ self.assertEqual(1, client1.search(q).total)
+ client2 = self.getCleanClient('idx2')
+ client2.create_index((TextField('foo'),), skip_initial_scan=True)
+ self.assertEqual(0, client2.search(q).total)
+
def testFilters(self):
conn = self.redis()
@@ -602,6 +636,25 @@ def testSummarize(self):
self.assertEqual('ACT I SCENE I. London. The palace. Enter KING HENRY, LORD JOHN OF LANCASTER, the EARL of WESTMORELAND, SIR... ',
doc.txt)
+ def testSummarizeDisabled(self):
+ # test NOOFFSETS
+ client = self.getCleanClient('idx')
+ client.create_index((TextField('txt'),), no_term_offsets=True)
+ client.add_document('doc1', txt='foo bar')
+ with self.assertRaises(Exception) as context:
+ client.search(Query('foo').summarize(fields=['txt']))
+ self.assertEqual('Cannot use highlight/summarize because NOOFSETS was specified at index level',
+ str(context.exception))
+
+ # test NOHL
+ client = self.getCleanClient('idx')
+ client.create_index((TextField('txt'),), no_highlight=True)
+ client.add_document('doc1', txt='foo bar')
+ with self.assertRaises(Exception) as context:
+ client.search(Query('foo').summarize(fields=['txt']))
+ self.assertEqual('Cannot use highlight/summarize because NOOFSETS was specified at index level',
+ str(context.exception))
+
def testAlias(self):
conn = self.redis()
with conn as r:
@@ -735,6 +788,35 @@ def testTextFieldSortableNostem(self):
self.assertIn('SORTABLE', response['attributes'][0])
self.assertIn('NOSTEM', response['attributes'][0])
+ def testMaxTextFields(self):
+ conn = self.redis()
+
+ with conn as r:
+ # Creating a client
+ client = Client('idx1', port=conn.port)
+ client.redis.flushdb()
+
+ # Creating the index definition
+ client.create_index((TextField('f0'),))
+ # Fill the index with fields
+ for x in range(1, 32):
+ client.alter_schema_add((TextField('f{}'.format(x)),))
+ # OK for now.
+
+ # Should be too many indexes
+ with self.assertRaises(redis.ResponseError):
+ client.alter_schema_add((TextField('f{}'.format(x)),))
+
+ # Creating new client
+ client = Client('idx2', port=conn.port)
+ client.redis.flushdb()
+
+ # Creating the index definition
+ client.create_index((TextField('f0'),), max_text_fields=True)
+ # Fill the index with fields
+ for x in range(1, 50):
+ client.alter_schema_add((TextField('f{}'.format(x)),))
+
def testAlterSchemaAdd(self):
conn = self.redis()