redis / redis-om-python

Object mapping, and more, for Redis and Python
MIT License
1.06k stars 108 forks source link

Is there a way to filter by multiple values of one field without "or" (IN query)? #605

Closed DennyD17 closed 2 months ago

DennyD17 commented 2 months ago

Is there something like IN query for fetching multiple documents by multiple values of one field?

Similar to SQL "SELECT * FROM foo WHERE bar in (1, 2, 3);"

wanderer056 commented 2 months ago

LSHIFT(<<) is the IN operator and RSHIFT(>>) is the NOT IN operator. For eg: To find the person with desired skill in the skills list. people = Person.find( (Person.skills << desired_skill) & (Person.address.city == city) ).all()

Above example taken from: https://github.com/redis-developer/redis-om-python-flask-skeleton-app/blob/main/app.py

DennyD17 commented 2 months ago

@wanderer056 Thank you for the response

In your example skills is an array field (List[str]) I'm talking about another thing. Can we fetch persons with ids 1 or 2 or 3 without using explicit OR?

By the way REDIS JSON supports MGET operator, but there's no mget method in JsonModel, just simple get... I used It instead of using multiple OR and FT SEARCH

wanderer056 commented 2 months ago

@DennyD17 This operator also works for the use case you said. Look at the below example:

class Player(JsonModel):
    class Meta:
        model_key_prefix = "player"
        index_name = "player_index"

    p_id: str = Field(index=True, primary_key=True)
    in_lobby: Optional[bool] = Field(index=False)
    status: int = Field(index=True)

friends_id = ["1","2","3"]
friend_query= Player.find(
(Player.p_id << friends_id) & (Player.status== Status.ONLINE.value)
)
online_friends_ids = await friend_query.all()

Above is the example to find online friends of a player. It will look for the Player with p_id in friends_id list and status online. Note: p_id is string field.

The field should be string as the LSHIFT(<<) operator generates tag query underneath. Tag is automatically generated by the redis-om if the data type is string. I don't think you can do this for a number field in Redis.

slorello89 commented 2 months ago

Pretty sure this question has been answered so I'm going to close it. Feel free to reopen if needed.

DennyD17 commented 1 month ago

@wanderer056 Thanks for the explanation

I don't think you can do this for a number field in Redis

@slorello89 Well, for cases when pk is a number field maybe implementing mget in JsonModel (and HashModel) would be an useful feature... and maybe redis JSON query would work faster than Redis Search query