Usage of FILTER with FT.CREATE

Hi, I am trying RediSearch 2.0 (v1.99.3) and it works amazing! I wanted to figure out a better practice for usage of FILTER with FT.CREATE.

(paragraph edited to specify the actual command)
From my understanding, when I say FT.CREATE idx:addr ON HASH PREFIX 1 address: FILTER @country:usa ... then RediSearch would setup idx:addr indexing only addresses in usa. But my command does not work as expected.

From my understanding, when I say FT.CREATE idx:addr ON HASH PREFIX 1 address: FILTER @streetnumber:455* ... then RediSearch would setup idx:addr indexing only addresses with street number starting with 455. But my command does not work as expected.

According to the documentation,

FILTER {filter} is a filter expression with the full RediSearch aggregation expression language. It is possible to use @__key to access the key that was just added/changed. A field can be used to set field name by passing 'FILTER @indexName=="myindexname"'

But the part aggregation expression language is,

query_string : The base filtering query that retrieves the documents. It follows the exact same syntax as the search query, including filters, unions, not, optional, etc.

I am wondering which one of == and @ is correct.

Could anyone tell me what I am missing? Thanks!

ht

@htkm you got it right the right is just a syntax issue.
The right syntax is @country=="usa" or @streetnumber=="455*"

If your streetnumber is numeric, you can use < and > as well.

I’ve created a small test with an example to your case -

def testCountry(env):
    conn = getConnectionByEnv(env)
    env.cmd('ft.create', 'idx1',
            'ON', 'HASH',
            'PREFIX', 1, 'address:',
            'FILTER', '@country=="usa"',
            'SCHEMA', 'business', 'text', 'country', 'text')

    conn.execute_command('hset', 'address:1', 'business', 'foo', 'country', 'usa')
    conn.execute_command('hset', 'address:2', 'business', 'bar', 'country', 'israel')

    env.expect('ft.search', 'idx1', '*').equal([1L, 'address:1', ['business', 'foo', 'country', 'usa']])
1 Like

Just a small comment on @ashtul replies, if by “445*” you meant prefix match then you need to use the ‘startswith’ function (which for some reason is not documented, I will take care to document it) :
startswith(@streetnumber, "445")

If you do not use the ‘startswith’ function the ‘==’ will check if streetnumber equals exactly “445*”

Thank you guys very much! I appreciate the code snippet also the tip. @meirsh, would you be able to let me know which lines or files I can look around functions like startswith?

@htkm take a look here: https://oss.redislabs.com/redisearch/Aggregations/#list_of_string_apply_functions

As I said the startswith still need to be documented.

Great. Thank you for the help!

1 Like