Querying Data within a Partition
Partitions are used to divide large data sets to provide quicker access and increase capability to distribute data among logical parts. In this tutorial, you will learn how to query data within a partition in Onyx Database.
Steps to Query Data within a Partition (Onyx Cloud Database)
1
Declare the Entities
Use the provided JSON schema to declare your entities with partitioning and deploy the database using this schema definition.
1{
2 "tables": [
3 {
4 "name": "CallLog",
5 "identifier": {
6 "name": "callLogId",
7 "generator": "Sequence",
8 "type": "Long"
9 },
10 "partition": "callFromAreaCode",
11 "attributes": [
12 {
13 "name": "callLogId",
14 "type": "Long",
15 "isNullable": false
16 },
17 {
18 "name": "destinationNumber",
19 "type": "String",
20 "isNullable": true
21 },
22 {
23 "name": "timeDateStarted",
24 "type": "Date",
25 "isNullable": true
26 },
27 {
28 "name": "isNSAListening",
29 "type": "Boolean",
30 "isNullable": false
31 },
32 {
33 "name": "callFromAreaCode",
34 "type": "Int",
35 "isNullable": true
36 }
37 ],
38 "relationships": [
39 {
40 "name": "callFrom",
41 "inverse": "callLogs",
42 "inverseClass": "CellPhone",
43 "type": "ManyToOne",
44 "fetchPolicy": "None",
45 "cascadePolicy": "None"
46 }
47 ],
48 "indexes": [
49 {
50 "name": "isNSAListeningIndex",
51 "attributes": ["isNSAListening"]
52 }
53 ]
54 },
55 {
56 "name": "CellPhone",
57 "identifier": {
58 "name": "cellPhoneNumber",
59 "generator": "None",
60 "type": "String"
61 },
62 "partition": "",
63 "attributes": [
64 {
65 "name": "cellPhoneNumber",
66 "type": "String",
67 "isNullable": false
68 },
69 {
70 "name": "areaCode",
71 "type": "Int",
72 "isNullable": true
73 }
74 ],
75 "relationships": [
76 {
77 "name": "callLogs",
78 "inverse": "callFrom",
79 "inverseClass": "CallLog",
80 "type": "OneToMany",
81 "fetchPolicy": "None",
82 "cascadePolicy": "None"
83 }
84 ],
85 "indexes": []
86 }
87 ],
88 "revisionDescription": "Schema for partitioned CallLog and CellPhone entities"
89}
- Ensure your schema defines all required attributes, including types, sizes, and nullability.
- The
partition
attribute specifies the attribute used for partitioning. - Relationships and indexes are optional but improve performance and enforce data integrity.
2
Populate Test Data in Different Partitions
Call logs are stored in partitions for area codes
555
and 123
. Below is an example of how to populate test data in different partitions.1// Create a call log for area code (555)
2const myPhoneNumber = {
3 cellPhoneNumber: "(555) 303-2322",
4 areaCode: 555
5};
6await db.save("CellPhone", myPhoneNumber);
7
8const callToMom = {
9 destinationNumber: "(555) 323-2222",
10 isNSAListening: true,
11 callFrom: myPhoneNumber,
12 callFromAreaCode: myPhoneNumber.areaCode
13};
14await db.save("CallLog", callToMom);
15
16const callToEdwardSnowden = {
17 destinationNumber: "(555) 122-2341",
18 isNSAListening: false,
19 callFrom: myPhoneNumber,
20 callFromAreaCode: myPhoneNumber.areaCode
21};
22await db.save("CallLog", callToEdwardSnowden);
23
24// Create a call log for area code (123)
25// Note: Identifiers are not unique among partitions. Since the entire object graph is saved,
26// it is possible in this example to have the same identifiers for a CallLog in area code 555 as well as 123
27
28const mySecretPhone = {
29 cellPhoneNumber: "(123) 936-3733",
30 areaCode: 123
31};
32await db.save("CellPhone", mySecretPhone);
33
34const callToSomeoneShady = {
35 destinationNumber: "(555) 322-1143",
36 isNSAListening: false,
37 callFrom: mySecretPhone,
38 callFromAreaCode: mySecretPhone.areaCode
39};
40await db.save("CallLog", callToSomeoneShady);
41
42const callToJoe = {
43 destinationNumber: "(555) 286-9987",
44 isNSAListening: true,
45 callFrom: mySecretPhone,
46 callFromAreaCode: mySecretPhone.areaCode
47};
48await db.save("CallLog", callToJoe);
- Each partition is stored in a separate physical storage.
- An entity"s primary key or identifier is not unique among different partitions.
- The partition should be pre-determined. It cannot be defined by runtime listeners.
3
Create a Query to Find NSA Monitored Calls
Use the query builder syntax to create a query that includes the partition and the
isNSAListening
flag. This query will fetch calls monitored by the NSA in the specified area code.1const nsaListeningCalls = await db.from("CallLog")
2 .where(eq("isNSAListening", true))
3 .inPartition(555)
4 .list();
5
6console.log(`NSA is only listening to ${nsaListeningCalls.length} call(s) in area code 555`);
- Use the
inPartition
method to specify the partition value. - The
isNSAListening
field is indexed, making the query highly optimized. - The query will return the number of calls monitored by the NSA in area code
555
.
Important Notes
- An entity"s primary key or identifier is not unique among different partitions.
- The partition should be pre-determined and cannot be defined by runtime listeners.
- Each partition is stored in a separate physical storage, improving performance and scalability.
Troubleshooting
- Data Not Appearing in Query Results: Ensure that you are querying the correct partition and that the partition value matches the data.
- Partition Attribute Not Set: Verify that the partition attribute is correctly annotated with
@Partition
and that it is assigned a value before saving the entity. - Query Performance Issues: Index the fields used in your queries to optimize performance.
Next Steps
Now that you have learned how to query data within a partition, you can explore more advanced querying techniques: