0

I am a newbie to Redis. I want to store and search over a list of custom objects in Redis cache. custom object has 4 attribute

  1. configKey
  2. configScope
  3. valueType
  4. configValue

Sample custom object

{"configScope":"country","configValue":"india","configKey":"country","valueType":"string"}
{"configScope":"integer","configValue":"3","configKey":"integer","valueType":"string"}
{"configScope":"sport","configValue":"sport","configKey":"sport","valueType":"string"}
{"configScope":"country","configValue":"india","configKey":"country","valueType":"string"}

couldn't understand how to store these object as i can efficiently search the string based configKey or configScope or configValue.

have written sample code but it is only giving result based on exact key

for (CustomObject model : list) {
    CustomObject ec = (CustomObject) model;
    syncCommands.lpush("orgId:EC:"+count++, ec.toString());
}

KeyScanCursor<String> cursor = syncCommands.scan(ScanArgs.Builder.limit(50).match("orgId:EC:10"));

while (!cursor.isFinished()) {
    for (String key : cursor.getKeys()) {
        List<String> value = syncCommands.lrange(key, 0, 50);
        System.out.println(key + " - " + value);
    }
   cursor = syncCommands.scan(cursor, 
   ScanArgs.Builder.limit(50).match("orgId:EC:10"));
}

Any idea or reference will be helpful.

TeamZ
  • 343
  • 6
  • 15
  • How you want to search, I mean search by configKey or by combination of configKey and configscope? List your queries, related to structure – tabreaz May 11 '20 at 09:57
  • basically all fields are searchable and independent of each other. either user can search over configKey or configValue or configScope. – TeamZ May 11 '20 at 11:21
  • 1
    Look into redisjson module, if you don't want to use modules then you have to index them separately using redis hashes, one per query type for ex, hashset key can be configScope:country and it's key is country-id and value can be serialised config object – tabreaz May 11 '20 at 12:20
  • @tabreaz do you have sample code for how to index them separately. – TeamZ May 11 '20 at 13:34
  • from your code the results are exact match as you are missing * after the search term **.match("orgId:EC:10*")** . – tabreaz May 11 '20 at 17:53

1 Answers1

1

You may try and see if redis Lexicographical indexes may help in your case, for example the sample document below can be stored in redis sorted set and do Lex search on it.

{"configScope":"country","configValue":"india","configKey":"country","valueType":"string"}

{"configScope":"country","configValue":"russia","configKey":"country","valueType":"string"}

127.0.0.1:6379> zadd cs:country 0 cv:russia:ck:country:vt:string 0 ck:country:cv:russia:vt:string
(integer) 2
127.0.0.1:6379> zadd cs:country 0 cv:india:ck:country:vt:string 0 ck:country:cv:india:vt:string
(integer) 2

Now to search configScope country and configValue india, you can do the following search

127.0.0.1:6379> zrangebylex cs:country "[cv:india" "(cv:india~"
1) "cv:india:ck:country:vt:string"

And Similarly to search configScope country with configKey country

127.0.0.1:6379> zrangebylex cs:country "[ck:country" "(ck:country~"
1) "ck:country:cv:india:vt:string"
2) "ck:country:cv:russia:vt:string"

I hope this will help you in getting started with this approach, for more information of lexicographical indexes in redis Secondary Indexing with Redis

tabreaz
  • 649
  • 4
  • 17
  • what would be my Range while search over key syncCommands.zrangebylex(key, Range) – TeamZ May 12 '20 at 07:25
  • as mentioned in the answer your Range will be **"[ck:country"** lower and **"(ck:country~"** upper for key **cs:country** to get all configKey **country** in configScope **country**. **syncCommands.zrangebylex("cs:country", new Range("[ck:country", "(ck:country~"));** – tabreaz May 12 '20 at 07:52
  • ` long addSize1 = syncCommands.zadd("cs:country", ScoredValue.from(1, Optional.of("cv:russia:ck:country:vt:string")),ScoredValue.from(2, Optional.of("ck:country:cv:russia:vt:string")), ScoredValue.from(4, Optional.of("cv:india:ck:country:vt:string")), ScoredValue.from(5, Optional.of("ck:country:cv:india:vt:string"))); System.out.println("zset = "+syncCommands.zrangebylex("cs:country",Range.create("[ck:country", " (ck:country~"))); ` showing empty result. – TeamZ May 12 '20 at 08:29
  • When you use sortedSet for lexicographical index the scores should be always 0. – tabreaz May 12 '20 at 08:34
  • even though i gave score as 0, still getting empty result long addSize1 = syncCommands.zadd("cs:country", ScoredValue.from(0, Optional.of("cv:russia:ck:country:vt:string")), ScoredValue.from(0, Optional.of("ck:country:cv:russia:vt:string")), ScoredValue.from(0, Optional.of("cv:india:ck:country:vt:string")), ScoredValue.from(0, Optional.of("ck:country:cv:india:vt:string"))); System.out.println("addSize1 = "+addSize1); System.out.println("zset = "+syncCommands.zrangebylex("cs:country",Range.create("ck:country", " (ck:country~"))); – TeamZ May 12 '20 at 08:38
  • your zrangebylex is missing **[**, try this syncCommands.zrangebylex("cs:country",Range.create("[ck:country", " (ck:country~")) – tabreaz May 12 '20 at 08:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213678/discussion-between-teamz-and-tabreaz). – TeamZ May 12 '20 at 09:02