Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 17 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ print(seq.json());
# But if you need more (like date, bytes, etc) we will add them without any problem.
# JSONiq has a rich type system.

rumble.bind('$c', (1,2,3,4, 5, 6))
print(rumble.jsoniq("""
for $v in $c
let $parity := $v mod 2
Expand All @@ -183,28 +182,24 @@ return { switch($parity)
case 1 return "odd"
default return "?" : $v
}
""").json())
""", c=(1,2,3,4, 5, 6)).json())

rumble.bind('$c', ([1,2,3],[4,5,6]))
print(rumble.jsoniq("""
for $i in $c
return [
for $j in $i
return { "foo" : $j }
]
""").json())
""", c=([1,2,3],[4,5,6])).json())

rumble.bind('$c', ({"foo":[1,2,3]},{"foo":[4,{"bar":[1,False, None]},6]}))
print(rumble.jsoniq('{ "results" : $c.foo[[2]] }').json())
print(rumble.jsoniq('{ "results" : $c.foo[[2]] }', c=({"foo":[1,2,3]},{"foo":[4,{"bar":[1,False, None]},6]})).json())

# It is possible to bind only one value. The it must be provided as a singleton tuple.
# This is because in JSONiq, an item is the same a sequence of one item.
rumble.bind('$c', (42,))
print(rumble.jsoniq('for $i in 1 to $c return $i*$i').json())
print(rumble.jsoniq('for $i in 1 to $c return $i*$i', c=(42,)).json())

# For convenience and code readability, you can also use bindOne().
rumble.bindOne('$c', 42)
print(rumble.jsoniq('for $i in 1 to $c return $i*$i').json())
print(rumble.jsoniq('for $i in 1 to $c return $i*$i', c=42).json())

##########################################################
##### Binding JSONiq variables to pandas DataFrames ######
Expand All @@ -217,8 +212,7 @@ data = {'Name': ['Alice', 'Bob', 'Charlie'],
pdf = pd.DataFrame(data);

# Binding a pandas dataframe
rumble.bind('$a',pdf);
seq = rumble.jsoniq('$a.Name')
seq = rumble.jsoniq('$a.Name', a=pdf)
# Getting the output as a pandas dataframe
print(seq.pdf())

Expand All @@ -239,13 +233,10 @@ data = [("Alice", 30), ("Bob", 25), ("Charlie", 35)];
columns = ["Name", "Age"];
df = spark.createDataFrame(data, columns);

# This is how to bind a JSONiq variable to a dataframe. You can bind as many variables as you want.
rumble.bind('$a', df);

# This is how to run a query. This is similar to spark.sql().
# Since variable $a was bound to a DataFrame, it is automatically declared as an external variable
# You can bind JSONiq variables to pyspark DataFrames as follows. You can bind as many variables as you want.
# Since variable $a is bound to a DataFrame, it is automatically declared as an external variable
# and can be used in the query. In JSONiq, it is logically a sequence of objects.
res = rumble.jsoniq('$a.Name');
res = rumble.jsoniq('$a.Name', a=df);

# There are several ways to collect the outputs, depending on the user needs but also
# on the query supplied.
Expand Down Expand Up @@ -278,14 +269,12 @@ df2 = spark.sql("SELECT * FROM myview").toDF("name");
df2.show();

# A DataFrame output by Spark SQL can be reused as input to a JSONiq query.
rumble.bind('$b', df2);
seq2 = rumble.jsoniq("for $i in 1 to 5 return $b");
seq2 = rumble.jsoniq("for $i in 1 to 5 return $b", b=df2);
df3 = seq2.df();
df3.show();

# And a DataFrame output by JSONiq can be reused as input to another JSONiq query.
rumble.bind('$b', df3);
seq3 = rumble.jsoniq("$b[position() lt 3]");
seq3 = rumble.jsoniq("$b[position() lt 3]", b=df3);
df4 = seq3.df();
df4.show();

Expand Down Expand Up @@ -335,7 +324,7 @@ for str in rdd.take(10):
# RumbleDB was already tested with up to 64 AWS machines and 100s of TBs of data.
# Of course the examples below are so small that it makes more sense to process the results locally with Python,
# but this shows how GBs or TBs of data obtained from JSONiq can be written back to disk.
seq = rumble.jsoniq("$a.Name");
seq = rumble.jsoniq("$a.Name", a=spark.createDataFrame(data, columns));
seq.write().mode("overwrite").json("outputjson");
seq.write().mode("overwrite").parquet("outputparquet");

Expand All @@ -349,6 +338,11 @@ Even more queries can be found [here](https://colab.research.google.com/github/R

# Latest updates

## Version 0.2.0 alpha 8
- Variables can now be bound to JSON values, pandas DataFrames or pyspark DataFrames with extra parameters to the rumble.jsoniq() call. It is no longer necessary to explicitly call bind(). This is similar to how DataFrames can be attached to views with extra parameters to spark.sql().
- rumble.lastResult is now correctly assigned also when partial data is returned (only with the partial data).
- Fixed issue with empty array constructors.

## Version 0.2.0 alpha 7
- rumble.lastResult now returns a pyspark/pandas DataFrame or rdd or tuple and no longer the sequence object.
- Enhance schema detection. When the detected static type of the overall query is DataFrame-compatible, it is now automatically possible to obtain the output as a DataFrame without explicitly giving a schema.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "jsoniq"
version = "0.2.0a7"
version = "0.2.0a8"
description = "Python edition of RumbleDB, a JSONiq engine"
requires-python = ">=3.11"
dependencies = [
Expand Down
Binary file modified src/jsoniq/jars/rumbledb-1.24.0.jar
Binary file not shown.
1 change: 1 addition & 0 deletions tests/test_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def test1(self):
}
""");
print(seq.json());
self.assertTrue(json.dumps(seq.json()) == json.dumps(({'store': 1, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 2, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 3, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 4, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 5, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 6, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 7, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 8, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 9, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 10, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 11, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 12, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 13, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 14, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 15, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 16, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 17, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 18, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 19, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 20, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 21, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 22, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 23, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 24, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 25, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 26, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 27, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 28, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 29, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 30, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 31, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 32, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 33, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 34, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 35, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 36, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 37, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 38, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 39, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 40, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 41, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 42, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 43, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 44, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 45, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 46, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 47, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 48, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 49, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 50, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 51, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 52, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 53, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 54, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 55, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 56, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 57, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 58, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 59, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 60, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 61, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 62, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 63, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 64, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 65, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 66, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 67, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 68, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 69, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 70, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 71, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 72, 'products': ['shirt', 'toaster', 'phone', 'blender', 'tv', 'socks', 'broiler']}, {'store': 73, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 74, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 75, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 76, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 77, 'products': ['toaster', 'phone', 'blender', 'tv', 'socks', 'broiler', 'shirt']}, {'store': 78, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 79, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 80, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 81, 'products': ['phone', 'blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster']}, {'store': 82, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 83, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 84, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 85, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 86, 'products': ['blender', 'tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone']}, {'store': 87, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 88, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 89, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 90, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 91, 'products': ['tv', 'socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender']}, {'store': 92, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 93, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 94, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 95, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 96, 'products': ['socks', 'broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv']}, {'store': 97, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 98, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 99, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']}, {'store': 100, 'products': ['broiler', 'shirt', 'toaster', 'phone', 'blender', 'tv', 'socks']})))

############################################################
###### Binding JSONiq variables to Python values ###########
Expand Down