Skip to content

Commit cea26aa

Browse files
authored
feat: support $NOT, $OR, $AND nested filter (#46)
* feat: support nested filters * feat: support nested filters. add README
1 parent 5618214 commit cea26aa

12 files changed

Lines changed: 1107 additions & 889 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ deploy-settings.xml
1010
# Idea
1111
.idea
1212
java-cosmos.iml
13+
.java-version
1314

1415
# Compiled class file
1516
*.class

README.md

Lines changed: 26 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,37 @@ java-cosmos is a client for Azure CosmosDB 's SQL API (also called documentdb fo
44

55
[![Java CI with Maven](https://github.com/thunderz99/java-cosmos/actions/workflows/maven.yml/badge.svg)](https://github.com/thunderz99/java-cosmos/actions/workflows/maven.yml)
66

7-
8-
97
## Background
108

119
* Microsoft's official Java CosmosDB client is verbose to use
1210

13-
14-
1511
## Disclaimer
1612

1713
* This is an alpha version, and features are focused to CRUD and find at present.
1814

19-
20-
2115
## Quickstart
2216

2317
### Add dependency
2418

2519
```xml
26-
2720
<!-- Add new dependency -->
2821

2922
<dependency>
3023
<groupId>com.github.thunderz99</groupId>
3124
<artifactId>java-cosmos</artifactId>
32-
<version>0.2.24</version>
25+
<version>0.2.25</version>
3326
</dependency>
34-
3527
```
3628

37-
38-
39-
### Start programming
29+
### Start programming
4030

4131
```java
42-
4332
import io.github.thunderz99.cosmos.Cosmos
4433

4534
public static void main(String[] args) {
4635
var db = new Cosmos(System.getenv("YOUR_CONNECTION_STRING")).getDatabase("Database1")
4736
db.upsert("Collection1", new User("id011", "Tom", "Banks"))
48-
37+
4938
var cond = Condition.filter(
5039
"id", "id010", // id equal to 'id010'
5140
"lastName", "Banks", // last name equal to Banks
@@ -54,7 +43,7 @@ public static void main(String[] args) {
5443
.sort("lastName", "ASC") //optional order
5544
.offset(0) //optional offset
5645
.limit(100); //optional limit
57-
46+
5847
var users = db.find("Collection1", cond).toList(User.class)
5948
}
6049

@@ -65,24 +54,20 @@ class User{
6554
public String lastName;
6655
public String location;
6756
public int age;
68-
57+
6958
public User(String id, String firstName, String lastName){
7059
this.id = id;
7160
this.firstName = firstName;
7261
this.lastName = lastName;
7362
}
7463
}
75-
7664
```
7765

78-
79-
8066
## More examples
8167

82-
### Work with partitions
68+
### Work with partitions
8369

8470
```java
85-
8671
// Save user into Coll:Collection1, partition:Users.
8772
// If you do not specify the partition. It will default to coll name.
8873
var db = new Cosmos(System.getenv("YOUR_CONNECTION_STRING")).getDatabase("Database1");
@@ -95,27 +80,23 @@ db.upsert("Collection1", new User("id011", "Tom", "Banks"), "Users");
9580
// "lastName": "Banks",
9681
// "_partition": "Users"
9782
// }
98-
9983
```
10084

10185
### Create database and collection dynamically
10286

10387
```java
104-
10588
var cosmos = new Cosmos(System.getenv("YOUR_CONNECTION_STRING"));
10689
var db = cosmos.createIfNotExist("Database1", "Collection1");
10790
db.upsert("Collection1", new User("id011", "Tom", "Banks"))
108-
91+
10992
// create a collection with uniqueIndexPolicy
11093
var uniqueKeyPolicy = Cosmos.getUniqueKeyPolicy(Set.of("/_uniqueKey1", "/_uniqueKey2"));
11194
var db = cosmos.createIfNotExist("Database1", "Collection2", uniqueKeyPolicy);
112-
11395
```
11496

11597
### CRUD
11698

11799
```java
118-
119100
var db = new Cosmos(System.getenv("YOUR_CONNECTION_STRING")).getDatabase("Database1");
120101

121102
// Create
@@ -133,24 +114,17 @@ db.upsert("Collection1", user1, "Users");
133114

134115
// Delete
135116
db.delete("Collection1", user1,id, "Users");
136-
137117
```
138118

139119
### Partial Update
140120

141121
```java
142-
143122
db.updatePartial("Collection", user1.id, Map.of("lastName", "UpdatedPartially"), "Users");
144-
145-
146123
```
147124

148-
149-
150125
### Complex queries
151126

152127
```java
153-
154128
var cond = Condition.filter(
155129
"id", "id010", // id equal to 'id010'
156130
"lastName", "Banks", // last name equal to Banks
@@ -167,52 +141,51 @@ db.updatePartial("Collection", user1.id, Map.of("lastName", "UpdatedPartially"),
167141
"tagIds ARRAY_CONTAINS", "T001", // see cosmosdb ARRAY_CONTAINS
168142
"tagIds ARRAY_CONTAINS_ANY", List.of("T001", "T002"), // see cosmosdb EXISTS
169143
"tags ARRAY_CONTAINS_ALL name", List.of("Java", "React"), // see cosmosdb EXISTS
170-
"SUB_COND_OR", List.of( // add an OR sub condition
144+
"$OR", List.of( // add an OR sub condition
171145
Condition.filter("position", "leader"), // subquery's fields/order/offset/limit will be ignored
172146
Condition.filter("organization.id", "executive_committee")
173147
),
174-
"SUB_COND_OR 2", List.of( // add another OR sub condition (name it SUB_COND_OR xxx in order to avoid the same key to a previous SUB_COND_OR )
148+
"$OR 2", List.of( // add another OR sub condition (name it $OR xxx in order to avoid the same key to a previous $OR )
175149
Condition.filter("position", "leader"), // subquery's fields/order/offset/limit will be ignored
176150
Condition.filter("organization.id", "executive_committee")
177151
),
178-
"SUB_COND_AND", List.of(
152+
"$AND", List.of(
179153
Condition.filter("tagIds ARRAY_CONTAINS_ALL", List.of("T001", "T002")).not() // A negative condition. see cosmosdb NOT
180154
Condition.filter("city", "Tokyo")
155+
),
156+
"$NOT", Map.of("lastName CONTAINS", "Willington"), // A negative query using $NOT
157+
"$NOT 2", Map.of("$OR 3", // A nested filter using $NOT and $OR
158+
List.of(
159+
Map.of("lastName", ""), // note they will do the same thing using Condition.filter or Map.of
160+
Map.of("age >=", 20)
161+
)
181162
)
182163
)
183164
.fields("id", "lastName", "age", "organization.name") // select certain fields
184165
.sort("lastName", "ASC") //optional sort
185166
.offset(0) //optional offset
186167
.limit(100); //optional limit
187-
188-
var users = db.find("Collection1", cond).toList(User.class);
189-
190168

169+
var users = db.find("Collection1", cond).toList(User.class);
191170
```
192171

193-
194-
195172
### Aggregates
196173

197174
```java
198-
199175
// support aggregate function: COUNT, AVG, SUM, MAX, MIN
200176
// see https://docs.microsoft.com/en-us/azure/cosmos-db/sql-query-aggregate-functions
201177
var aggregate = Aggregate.function("COUNT(1) AS facetCount").groupBy("location", "gender");
202-
178+
203179
var result = db.aggregate("Collection1", aggregate, Condition.filter("age >=", 20));
204180

205181
// will generate a sql like this:
206182
/* SELECT COUNT(1) as facetCount, c.location, c.gender WHERE age >= 20 GROUP BY c.location, c.gender
207183
*/
208184
```
209185

210-
211-
212186
### Cross-partition queries
213187

214188
```java
215-
216189
// simple query
217190
var cond = Condition.filter("id", "M001").crossPartition(true);
218191
// when crossPartition is set to true, the partition filter will be ignored.
@@ -224,11 +197,8 @@ db.updatePartial("Collection", user1.id, Map.of("lastName", "UpdatedPartially"),
224197
var aggregate = Aggregate.function("COUNT(1) as facetCount").groupBy("_partition");
225198
var cond = Condition.filter().crossPartition(true);
226199
var result = db.aggregate("Collection1", aggregate, cond);
227-
228200
```
229201

230-
231-
232202
### Raw SQL queries
233203

234204
```java
@@ -237,34 +207,31 @@ db.updatePartial("Collection", user1.id, Map.of("lastName", "UpdatedPartially"),
237207
" FROM Families f\n" +
238208
" JOIN c IN f.children WHERE f.address.state = @state ORDER BY f.id ASC";
239209

240-
var params = new SqlParameterCollection(new SqlParameter("@state", "NY"));
210+
var params = new SqlParameterCollection(new SqlParameter("@state", "NY"));
241211

242-
var cond = Condition.rawSql(queryText, params);
243-
var children = db.find(coll, cond, partition);
212+
var cond = Condition.rawSql(queryText, params);
213+
var children = db.find(coll, cond, partition);
244214

245215
// use raw sql as a where condition
246216
var cond = Condition.filter(SubConditionType.AND, List.of(
247217
Condition.filter("gender", "female"),
248218
Condition.rawSql("1=1"));
249-
219+
250220
// use raw sql as a where condition with params
251221
var params = new SqlParameterCollection(new SqlParameter("@state", "%NY%"));
252222

253223
var cond = Condition.filter(
254-
"SUB_COND_AND",
224+
"$AND",
255225
List.of(
256226
Condition.filter("gender", "female"),
257227
Condition.rawSql("c.state LIKE @state", params)
258228
),
259-
"SUB_COND_AND another", // name it SUB_COND_OR xxx in order to avoid the same key to a previous SUB_COND_AND
229+
"$AND another", // name it $AND xxx in order to avoid the same key to a previous $AND
260230
List.of(
261231
Condition.filter("age > ", "22"),
262232
Condition.rawSql("c.address != \"\" ")
263233
)
264234
);
265-
235+
266236
db.find("Collection1", cond, "Partition1");
267-
268-
269237
```
270-

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>com.github.thunderz99</groupId>
55
<artifactId>java-cosmos</artifactId>
66
<packaging>jar</packaging>
7-
<version>0.2.24</version>
7+
<version>0.2.25</version>
88
<name>${project.groupId}:${project.artifactId}$</name>
99
<description>A lightweight Azure CosmosDB client for Java</description>
1010
<url>https://github.com/thunderz99/java-cosmos</url>

0 commit comments

Comments
 (0)