Conversation
Contributor
|
thank you for the contribution. there's a small typo in https://github.com/RedisJSON/RedisJSON/pull/1465/files#diff-fe8692f5492557c8fe9633a9784c4369d58ae070dd14d9e63696f57256a4efe9R1047 (missing a can you please add tests verifying correctness of both the happy path as well as any error paths. eg something like def testFilterCommandErrors(env):
env.expect('JSON.FILTER', '{doc}:1', '$').raiseError()
env.expect('JSON.FILTER', '{doc}:1', '$', '$[?(@.a>0)]').raiseError()
env.cmd('JSON.SET', '{doc}:1', '$', '{"a":1}')
env.expect('JSON.FILTER', '{doc}:1', '$', '$[?(@.a>').raiseError()
env.expect('JSON.FILTER', '{doc}:1', '$..[', '$[?(@.a>0)]').raiseError()def testFilterCommandBasic(env):
env.cmd('JSON.SET', '{doc}:1', '$', '{"name":"Alice","age":30,"city":"NYC","active":true}')
env.cmd('JSON.SET', '{doc}:2', '$', '{"name":"Bob","age":25,"city":"LA","active":false}')
env.cmd('JSON.SET', '{doc}:3', '$', '{"name":"Charlie","age":35,"city":"NYC","active":true}')
env.cmd('JSON.SET', '{doc}:4', '$', '{"name":"Diana","age":28,"city":"SF","active":true}')
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:2', '{doc}:3', '{doc}:4', '$', '$[?(@.active==true)]')
env.assertEqual(len(res), 4)
env.assertNotEqual(res[0], None)
env.assertEqual(res[1], None)
env.assertNotEqual(res[2], None)
env.assertNotEqual(res[3], None)
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:2', '{doc}:3', '{doc}:4', '$.name', '$[?(@.age>28)]')
env.assertEqual(len(res), 4)
env.assertEqual(json.loads(res[0]), ["Alice"])
env.assertEqual(res[1], None)
env.assertEqual(json.loads(res[2]), ["Charlie"])
env.assertEqual(res[3], None)
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:2', '{doc}:3', '{doc}:4', '$', '$[?(@.city=="NYC")]')
env.assertEqual(len(res), 4)
env.assertNotEqual(res[0], None)
env.assertEqual(res[1], None)
env.assertNotEqual(res[2], None)
env.assertEqual(res[3], None)
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:missing', '{doc}:3', '$', '$[?(@.active==true)]')
env.assertEqual(len(res), 3)
env.assertNotEqual(res[0], None)
env.assertEqual(res[1], None)
env.assertNotEqual(res[2], None)
env.cmd('SET', '{doc}:wrong_type', 'not a json')
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:wrong_type', '{doc}:3', '$', '$[?(@.active==true)]')
env.assertEqual(len(res), 3)
env.assertNotEqual(res[0], None)
env.assertEqual(res[1], None)
env.assertNotEqual(res[2], None)
env.cmd('JSON.SET', '{doc}:nested1', '$', '{"user":{"name":"Eve","score":85},"status":"active"}')
env.cmd('JSON.SET', '{doc}:nested2', '$', '{"user":{"name":"Frank","score":92},"status":"inactive"}')
env.cmd('JSON.SET', '{doc}:nested3', '$', '{"user":{"name":"Grace","score":78},"status":"active"}')
res = env.cmd('JSON.FILTER', '{doc}:nested1', '{doc}:nested2', '{doc}:nested3', '$.user.name', '$[?(@.user.score>80)]')
env.assertEqual(len(res), 3)
env.assertEqual(json.loads(res[0]), ["Eve"])
env.assertEqual(json.loads(res[1]), ["Frank"])
env.assertEqual(res[2], None)
env.cmd('JSON.SET', '{doc}:arr1', '$', '{"items":[1,2,3],"count":3}')
env.cmd('JSON.SET', '{doc}:arr2', '$', '{"items":[4,5],"count":2}')
env.cmd('JSON.SET', '{doc}:arr3', '$', '{"items":[6,7,8,9],"count":4}')
res = env.cmd('JSON.FILTER', '{doc}:arr1', '{doc}:arr2', '{doc}:arr3', '$.count', '$[?(@.count>2)]')
env.assertEqual(len(res), 3)
env.assertEqual(json.loads(res[0]), [3])
env.assertEqual(res[1], None)
env.assertEqual(json.loads(res[2]), [4])
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:2', '{doc}:3', '.name', '.[?(@.age>28)]')
env.assertEqual(len(res), 3)
env.assertEqual(json.loads(res[0]), "Alice")
env.assertEqual(res[1], None)
env.assertEqual(json.loads(res[2]), "Charlie")
res = env.cmd('JSON.FILTER', '{doc}:1', '{doc}:2', '{doc}:3', '$', '$[?(@.age>100)]')
env.assertEqual(len(res), 3)
env.assertEqual(res[0], None)
env.assertEqual(res[1], None)
env.assertEqual(res[2], None)
env.cmd('JSON.SET', '{doc}:multi1', '$', '{"a":1,"nested":{"a":2,"b":3}}')
env.cmd('JSON.SET', '{doc}:multi2', '$', '{"a":4,"nested":{"a":5,"b":6}}')
res = env.cmd('JSON.FILTER', '{doc}:multi1', '{doc}:multi2', '$..a', '$[?(@.a>0)]')
env.assertEqual(len(res), 2)
env.assertEqual(json.loads(res[0]), [1, 2])
env.assertEqual(json.loads(res[1]), [4, 5])def testFilterCommandComplex(env):
env.cmd('JSON.SET', '{doc}:store1', '$', '{"store":{"book":[{"category":"reference","price":8.95},{"category":"fiction","price":12.99}]}}')
env.cmd('JSON.SET', '{doc}:store2', '$', '{"store":{"book":[{"category":"fiction","price":8.99},{"category":"fiction","price":22.99}]}}')
env.cmd('JSON.SET', '{doc}:store3', '$', '{"store":{"book":[{"category":"reference","price":15.00}]}}')
res = env.cmd('JSON.FILTER', '{doc}:store1', '{doc}:store2', '{doc}:store3', '$.store.book[*].price', '$.store.book[?(@.category=="fiction")]')
env.assertEqual(len(res), 3)
env.assertNotEqual(res[0], None)
env.assertNotEqual(res[1], None)
env.assertEqual(res[2], None)
env.cmd('JSON.SET', '{doc}:deep1', '$', '{"level1":{"level2":{"value":10}}}')
env.cmd('JSON.SET', '{doc}:deep2', '$', '{"level1":{"level2":{"value":5}}}')
res = env.cmd('JSON.FILTER', '{doc}:deep1', '{doc}:deep2', '$..value', '$..level2[?(@.value>7)]')
env.assertEqual(len(res), 2)
env.assertEqual(json.loads(res[0]), [10])
env.assertEqual(res[1], None) |
Author
|
@ephraimfeldblum Sure thing, sorry about it - was actually copy-pasting from my local fork (which pre-dates the macro usage) so didnt check it in-depth. I'll get to it today - will also differentiate |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Suggestion for an API -
JSON.FILTERSyntax
Description
Complexity:
Basically a lightweight way of filtering and accessing the JSON tree at different points while adhering to JSONPath.
This allows user to have more complex operations without suffering a big performance impact, so that we can do things such as:
$.[?($.type == "metadata")]- to fetch any element that is a "metadata"arr.filter((item) => predicate(item))without having to first fetch the entirearrImplementation details:
NOTE: This is an initial draft, it lacks tests and a more in-depth SPEC file, but this is mainly to discuss the concept, idea and reasoning of why this should/not be added