|
13 | 13 | "id": "3b936925-e295-489a-b508-2b99c0160217", |
14 | 14 | "metadata": {}, |
15 | 15 | "source": [ |
16 | | - "# CRUD: Find in arrays\n", |
17 | | - " " |
| 16 | + "# CRUD: Querying Array Fields\n", |
| 17 | + "\n", |
| 18 | + "## How can we query array fields in MongoDB?\n", |
| 19 | + "\n", |
| 20 | + "MongoDB lets us [query an array](https://www.mongodb.com/docs/manual/tutorial/query-arrays/?utm_campaign=devrel&utm_source=third-part-content&utm_medium=cta&utm_content=crud-operations-java-workshop&utm_term=ricardo.mello) fields in different ways depending on the matching behavior we want.\n", |
| 21 | + "\n", |
| 22 | + "In this section, we will use operators such as `all()`, `in()`, and `eq()` to find documents where array fields contain specific values, multiple values, or exact array matches." |
18 | 23 | ] |
19 | 24 | }, |
20 | 25 | { |
21 | 26 | "cell_type": "markdown", |
22 | 27 | "id": "dependent-boundary", |
23 | 28 | "metadata": {}, |
24 | 29 | "source": [ |
25 | | - "## Startup code\n" |
| 30 | + "## Startup code\n", |
| 31 | + "\n", |
| 32 | + "This cell imports the MongoDB Java Driver, connects to MongoDB, and initializes the `library` database and `books` collection used in the examples." |
26 | 33 | ] |
27 | 34 | }, |
28 | 35 | { |
|
46 | 53 | "import com.mongodb.client.MongoCollection;\n", |
47 | 54 | "import com.mongodb.client.FindIterable;\n", |
48 | 55 | "\n", |
| 56 | + "import static com.mongodb.client.model.Projections.include;\n", |
| 57 | + "\n", |
49 | 58 | "import static com.mongodb.client.model.Filters.eq;\n", |
50 | 59 | "import static com.mongodb.client.model.Filters.all;\n", |
51 | 60 | "import static com.mongodb.client.model.Filters.in;\n", |
52 | 61 | "\n", |
53 | 62 | "import org.bson.Document;\n", |
54 | 63 | "import org.bson.conversions.Bson;\n", |
55 | | - "import org.bson.json.JsonWriterSettings;\n", |
56 | 64 | "\n", |
57 | | - "import java.util.ArrayList;\n", |
58 | 65 | "import java.util.List;\n", |
59 | 66 | "\n", |
| 67 | + "\n", |
| 68 | + "// Configure SLF4J Simple Logger to suppress MongoDB driver logs in the notebook output.\n", |
| 69 | + "System.setProperty(\"org.slf4j.simpleLogger.defaultLogLevel\", \"off\");\n", |
| 70 | + "System.setProperty(\"org.slf4j.simpleLogger.log.org.mongodb.driver\", \"off\");\n", |
| 71 | + "\n", |
60 | 72 | "// Set your connection String\n", |
61 | 73 | "String connectionString = \"mongodb://admin:mongodb@localhost:27017/\";\n", |
62 | 74 | "\n", |
|
78 | 90 | "id": "automatic-fisher", |
79 | 91 | "metadata": {}, |
80 | 92 | "source": [ |
81 | | - "## Find all books containing one genre\n" |
| 93 | + "## Find books that contain `Poetry`\n", |
| 94 | + "\n", |
| 95 | + "In this example, we use [`eq()`](https://www.mongodb.com/docs/manual/reference/operator/query/eq/?utm_campaign=devrel&utm_source=third-part-content&utm_medium=cta&utm_content=crud-operations-java-workshop&utm_term=ricardo.mello) to find books where the `genres` array contains the value `\"Poetry\"`.\n" |
82 | 96 | ] |
83 | 97 | }, |
84 | 98 | { |
|
92 | 106 | }, |
93 | 107 | "outputs": [], |
94 | 108 | "source": [ |
95 | | - "Bson poetryBooks = eq(\"genres\", \"Poetry\");\n", |
96 | | - "books.find(poetryBooks)\n", |
| 109 | + "Bson filter = eq(\"genres\", \"Poetry\");\n", |
| 110 | + "Bson projection = include(\"title\", \"genres\");\n", |
| 111 | + "\n", |
| 112 | + "books.find(filter)\n", |
| 113 | + " .projection(projection)\n", |
97 | 114 | " .forEach(b -> System.out.println(\"Book: \" + b.toJson()));" |
98 | 115 | ] |
99 | 116 | }, |
|
102 | 119 | "id": "handled-symbol", |
103 | 120 | "metadata": {}, |
104 | 121 | "source": [ |
105 | | - "## Find all books containing the listed genres (AND)" |
| 122 | + "## Find books that contain both `Family Life` and `Fiction` (AND)\n", |
| 123 | + "\n", |
| 124 | + "In this example, we use [`all()`](https://www.mongodb.com/docs/manual/reference/operator/query/all/?utm_campaign=devrel&utm_source=third-part-content&utm_medium=cta&utm_content=crud-operations-java-workshop&utm_term=ricardo.mello) to find books where the `genres` array contains both `\"Family Life\"` and `\"Fiction\"`.\n" |
106 | 125 | ] |
107 | 126 | }, |
108 | 127 | { |
|
116 | 135 | }, |
117 | 136 | "outputs": [], |
118 | 137 | "source": [ |
119 | | - "Bson familyLifeAndFictionBooks = all(\"genres\", \"Family Life\", \"Fiction\");\n", |
| 138 | + "filter = all(\"genres\", \"Family Life\", \"Fiction\");\n", |
120 | 139 | "\n", |
121 | | - "books.find(familyLifeAndFictionBooks)\n", |
| 140 | + "books.find(filter)\n", |
| 141 | + " .projection(projection)\n", |
122 | 142 | " .forEach(b -> System.out.println(\"Book: \" + b.toJson()));" |
123 | 143 | ] |
124 | 144 | }, |
|
127 | 147 | "id": "9f6caab3", |
128 | 148 | "metadata": {}, |
129 | 149 | "source": [ |
130 | | - "## Find all books containing at least one of the listed genres (OR)" |
| 150 | + "## Find books that contain `Family Life` or `Fiction` (OR)\n", |
| 151 | + "\n", |
| 152 | + "In this example, we use [`in()`](https://www.mongodb.com/docs/manual/reference/operator/query/in/?utm_campaign=devrel&utm_source=third-part-content&utm_medium=cta&utm_content=crud-operations-java-workshop&utm_term=ricardo.mello) to find books where the `genres` array contains either `\"Family Life\"` or `\"Fiction\"`.\n" |
131 | 153 | ] |
132 | 154 | }, |
133 | 155 | { |
|
141 | 163 | }, |
142 | 164 | "outputs": [], |
143 | 165 | "source": [ |
144 | | - "Bson familyLifeOrFictionBooks = in(\"genres\", \"Family Life\", \"Fiction\");\n", |
| 166 | + "filter = in(\"genres\", \"Family Life\", \"Fiction\");\n", |
145 | 167 | "\n", |
146 | | - "books.find(familyLifeOrFictionBooks)\n", |
| 168 | + "books.find(filter)\n", |
| 169 | + " .projection(projection)\n", |
147 | 170 | " .forEach(b -> System.out.println(\"Book: \" + b.toJson()));" |
148 | 171 | ] |
149 | 172 | }, |
|
152 | 175 | "id": "1e62db28", |
153 | 176 | "metadata": {}, |
154 | 177 | "source": [ |
155 | | - "## Don't make this mistake!\n", |
| 178 | + "## Understanding exact array matches\n", |
156 | 179 | "\n", |
157 | | - "The query below will try to find books that have exactly two genres (Poetry and Fiction) in the designated order. The query looks for an exact match of the array. Usually we want to search inside the array." |
| 180 | + "When using [`eq()`](https://www.mongodb.com/docs/manual/reference/operator/query/eq/?utm_campaign=devrel&utm_source=third-part-content&utm_medium=cta&utm_content=crud-operations-java-workshop&utm_term=ricardo.mello) with an array, MongoDB looks for an **exact array match**.\n", |
| 181 | + "\n", |
| 182 | + "This means:\n", |
| 183 | + "- the values must be the same\n", |
| 184 | + "- the order must also match exactly\n", |
| 185 | + "\n", |
| 186 | + "For example, the query below returns a document because the `genres` array is exactly `[\"Poetry\", \"American\"]`." |
158 | 187 | ] |
159 | 188 | }, |
160 | 189 | { |
|
168 | 197 | }, |
169 | 198 | "outputs": [], |
170 | 199 | "source": [ |
171 | | - "Bson poetryAndFictionBooks = eq(\"genres\", Arrays.asList(\"Poetry\", \"Fiction\"));\n", |
| 200 | + "filter = eq(\"genres\", List.of(\"Poetry\", \"American\"));\n", |
172 | 201 | "\n", |
173 | | - "books.find(poetryAndFictionBooks)\n", |
174 | | - " .forEach(b -> System.out.println(\"Book: \" + b.toJson()));" |
| 202 | + "Document result = books.find(filter).projection(projection).first();\n", |
| 203 | + "\n", |
| 204 | + "if (result != null) {\n", |
| 205 | + " System.out.println(\"Book: \" + result.toJson());\n", |
| 206 | + "} else {\n", |
| 207 | + " System.out.println(\"No matching books were found.\");\n", |
| 208 | + "}" |
| 209 | + ] |
| 210 | + }, |
| 211 | + { |
| 212 | + "cell_type": "markdown", |
| 213 | + "id": "7b829347", |
| 214 | + "metadata": {}, |
| 215 | + "source": [ |
| 216 | + "However, if we invert the values to `[\"American\", \"Poetry\"]`, the query does not return any documents because the array order no longer matches the stored document exactly." |
| 217 | + ] |
| 218 | + }, |
| 219 | + { |
| 220 | + "cell_type": "code", |
| 221 | + "execution_count": null, |
| 222 | + "id": "e5d36e87", |
| 223 | + "metadata": { |
| 224 | + "vscode": { |
| 225 | + "languageId": "java" |
| 226 | + } |
| 227 | + }, |
| 228 | + "outputs": [], |
| 229 | + "source": [ |
| 230 | + "filter = eq(\"genres\", List.of(\"American\", \"Poetry\"));\n", |
| 231 | + "\n", |
| 232 | + "Document result = books.find(filter).projection(projection).first();\n", |
| 233 | + "\n", |
| 234 | + "if (result != null) {\n", |
| 235 | + " System.out.println(\"Book: \" + result.toJson());\n", |
| 236 | + "} else {\n", |
| 237 | + " System.out.println(\"No matching books were found.\");\n", |
| 238 | + "}" |
| 239 | + ] |
| 240 | + }, |
| 241 | + { |
| 242 | + "cell_type": "markdown", |
| 243 | + "id": "aa28eb2d", |
| 244 | + "metadata": {}, |
| 245 | + "source": [ |
| 246 | + "## Summary\n", |
| 247 | + "\n", |
| 248 | + "In this section, we learned different ways to query array fields in MongoDB using operators such as `eq()`, `all()`, and `in()`.\n", |
| 249 | + "\n", |
| 250 | + "We also explored how exact array matching works, including the importance of element order when comparing entire arrays with `eq()`." |
175 | 251 | ] |
176 | 252 | } |
177 | 253 | ], |
|
0 commit comments