Closed kurtisane closed 11 months ago
Hi @kurtisane, Redis OM .NET is a RediSearch client, DragonflyDB's implementation of the RediSearch API is new (I think they just officially launched the beta last week). But what I will tell you is that in RediSearch terms - "@FullName:{\"Albert Einstein\"}"
is not the query for Albert Einstein
but rather "Albert Einstein"
. Redis OM also automatically escapes spaces in query strings, which, evidently, dragonfly's query parser chokes on. This is considered best practice in RediSearch.
RediSearch is an RSAL (redis source available license) module so DragonFly couldn't legally copy it wholesale, they could only try to imitate its API, so quirks like this are inevitable.
The correct resolution for you would be:
Connection.Search
- you can create your own RedisQuery
and pass that, you'll have to write all your own queries though.My recommendation would be the first. Perhaps I'm biased as I work for Redis, but that's the only one I can guarantee will work. Assuming you are running your own DragonFly instances, and Dragonfly has kept faith with the modules API, you might even be able to use RediSearch with DragonFly, I know of Redis OM .NET users that use KeyDB, another one of the "Redis, but multithreaded!" projects, with RediSearch
Hi @slorello89, thank you for the explainer !
I understand the whole situation. The reason why I created a issue here is that I find the query created by Redis OM a little weird.
When looking into the FT.SEARCH command docs the query is wrapt into quotation marks but when looking at the command send its wrapt in braces. Is that fine ?
Hi @kurtisane - RediSearch calls for tag fields to be searched with the queried text surrounded by braces. Let's take an example:
[Document(StorageType = StorageType.Json)]
public class Doc
{
[Indexed] public string Name { get; set; }
}
here Name
is Indexed
meaning, since it's a string, it will be indexed as a Tag.
the query:
var first = collection.First(x => x.Name == "foo bar");
will produce the RediSearch query:
"FT.SEARCH" "doc-idx" "(@Name:{foo\\ bar})" "LIMIT" "0" "1"
in the monitor, the parentheses are to ensure it's all grouped properly. Then @Name:{foo\ bar}
, is the query. The double \
shows up in the monitor for quality-of-life reasons, it makes it easier for you to copy/paste the output back into the CLI, over the wire Redis is only receiving the first \
. The quotation marks around the entire query and each individual argument is another quality-of-life thing to make copy/pasting the command into the CLI easier. I don't want to get too deep into the RESP protocol - but this is a reflection of RESP, in that each argument surrounded by quotation marks is a separate parameter sent to Redis over the RESP protocol.
When you look at the FT.SEARCH docs, you'll see that there are multiple ways to structure a query, a query can just be a simple word:
FT.SEARCH books-idx "wizard"
It can be a field with a word preceding it with no braces:
FT.SEARCH books-idx "@title:dogs"
It can be two numbers in braces:
FT.SEARCH books-idx "@published_at:[2020 2021]"
It can be three numbers and a distance unit in braces:
FT.SEARCH restaurants-idx "@location:[-122.41 37.77 5 km]"
All of these are legal RediSearch searches, but for other field types TEXT
, TEXT
, NUMERIC
, GEO
respectively.
I'm assuming the TEXT
queries are what you are getting confused by, those are full-text search fields, as opposed to TAG
fields, where are closer to exact matches.
This is all more information than you need, the whole point of Redis OM is that you don't have to worry about any of this unless you want to, or are troubleshooting a server that does query parsing differently. The bottom line is that yes, Redis OM is writing the queries correctly.
Nothing really to be done about this, so closing.
I'm running the example project of Redis OM for .Net.
https://github.com/redis/redis-om-dotnet/tree/main/examples/Redis.OM.CreateIndexStore
Using the Redis Stack everything works fine and the Program can run without any issues.
docker run -p 6379:6379 -p 8001:8001 redis/redis-stack
Since I'm interested in DragonflyDB I have noticed that the Dragonfly Server is not compatible with Redis OM / Redis Search in every point. After digging in a little more I noticed some inconsistency.
According to docs this query should not work : https://redis.io/docs/interact/search-and-query/query/exact-match/
"FT.SEARCH" "customer-idx" "(@FullName:{Albert\\ Einstein})" "LIMIT" "0" "1" // What I see in the RedisInsight Profiler
orFT.SEARCH customer-idx (@FullName:{Albert\ Einstein}) LIMIT 0 1 // What I see in Code
This results in a Query Syntax error on Dragonfly, which from my understanding of the docs seems to be valid. But the Redis Server / Redis Search Module handles this fine.
This in return works on Dragonfly but not on Redis:
FT.SEARCH customer-idx "@FullName:{\"Albert Einstein\"}" LIMIT 0 1
This seems to alight with the docs better. The only missing information in the docs are handling of spaces in tags. Therefore the quotes around the tag with spaces are not defined I would say.
I don't really know where the issue is because from the perspective of Redis OM with Redis Stack everything works fine, but not according to the docs.