|
| 1 | +# Migrating |
| 2 | + |
| 3 | +## v6 to v7 |
| 4 | + |
| 5 | +### Configuration changes |
| 6 | + |
| 7 | +The `db.useDatabase` method has been deprecated in v7. |
| 8 | + |
| 9 | +Previously the primary use of this method was to set the database name of the |
| 10 | +arangojs instance. The database name can now be specified using the |
| 11 | +`databaseName` option in the arangojs configuration: |
| 12 | + |
| 13 | +```diff |
| 14 | + const db = new Database({ |
| 15 | + url: "http://localhost:8529", |
| 16 | ++ databaseName: "my_database", |
| 17 | + }); |
| 18 | +-db.useDatabase("my_database"); |
| 19 | +``` |
| 20 | + |
| 21 | +### Shared connection pool |
| 22 | + |
| 23 | +It is now possible to have multiple `Database` objects using the same |
| 24 | +underlying connection pool: |
| 25 | + |
| 26 | +```diff |
| 27 | +-const db1 = new Database(); |
| 28 | +-db1.useDatabase("database1"); |
| 29 | +-const db2 = new Database(); |
| 30 | +-db2.useDatabase("database2"); |
| 31 | ++const db1 = new Database({ databaseName: "database1" }); |
| 32 | ++const db2 = db1.database("database2"); |
| 33 | +``` |
| 34 | + |
| 35 | +### Indexes |
| 36 | + |
| 37 | +The helper methods for creating specific index types, e.g. `createHashIndex`, |
| 38 | +have been removed and replaced with the generic `ensureIndex` method (which |
| 39 | +was previously called `createIndex`): |
| 40 | + |
| 41 | +```diff |
| 42 | +-await collection.createGeoIndex(["lat", "lng"]); |
| 43 | ++await collection.createIndex({ type: "geo", fields: ["lat", "lng"] }); |
| 44 | +``` |
| 45 | + |
| 46 | +### Document and edge collections |
| 47 | + |
| 48 | +Version 7 no longer provides different methods for accessing document and edge |
| 49 | +collections as both types are now implemented using the same underlying class: |
| 50 | + |
| 51 | +```diff |
| 52 | + const myDocumentCollection = db.collection("documents"); |
| 53 | +-const myEdgeCollection = db.edgeCollection("edges"); |
| 54 | ++const myEdgeCollection = db.collection("edges"); |
| 55 | +``` |
| 56 | + |
| 57 | +When using TypeScript the collection instances can still be cast to the more |
| 58 | +specific `DocumentCollection` and `EdgeCollection` interfaces: |
| 59 | + |
| 60 | +```ts |
| 61 | +interface EdgeType { |
| 62 | + color: string; |
| 63 | +} |
| 64 | +const myEdgeCollection = db.collection("edges") as EdgeCollection<EdgeType>; |
| 65 | +``` |
| 66 | + |
| 67 | +### Saving edge documents |
| 68 | + |
| 69 | +The `save` method no longer supports positional arguments for `_from` and `_to` |
| 70 | +values. These now need to be supplied as part of the document data: |
| 71 | + |
| 72 | +```diff |
| 73 | + await edges.save( |
| 74 | +- "vertices/start", |
| 75 | +- "vertices/end", |
| 76 | +- { color: "red" } |
| 77 | ++ { _from: "vertices/start", _to: "vertices/end", color: "red" } |
| 78 | + ); |
| 79 | +``` |
| 80 | + |
| 81 | +### Accessing documents |
| 82 | + |
| 83 | +The `edge` method has been removed from the low-level collection API as it was |
| 84 | +an alias for the `document` method, which still exists: |
| 85 | + |
| 86 | +```diff |
| 87 | +-const edges = db.edgeCollection("edges"); |
| 88 | ++const edges = db.collection("edges"); |
| 89 | + |
| 90 | +-const edge = await edges.edge("my-edge"); |
| 91 | ++const edge = await edges.document("my-edge"); |
| 92 | +``` |
| 93 | + |
| 94 | +Graph vertex and edge collections instead only retain their specific `vertex` |
| 95 | +and `edge` methods which access the collection using the high-level graph API: |
| 96 | + |
| 97 | +```diff |
| 98 | + const vertices = graph.vertexCollection("vertices"); |
| 99 | +-const vertex = await vertices.document("my-vertex"); |
| 100 | ++const vertex = await vertices.vertex("my-vertex"); |
| 101 | + |
| 102 | + const edges = graph.edgeCollection("edges"); |
| 103 | +-const edge = await edges.document("my-edge"); |
| 104 | ++const edge = await edges.edge("my-edge"); |
| 105 | +``` |
| 106 | + |
| 107 | +### Graph collections |
| 108 | + |
| 109 | +Graph vertex and edge collections no longer implement the generic collection |
| 110 | +API methods to avoid confusion between operations that are aware of the graph |
| 111 | +definition (and can trigger graph-related side-effects) and those that directly |
| 112 | +access low-level operations. |
| 113 | + |
| 114 | +As a convenience both graph collection types still provide access to the |
| 115 | +low-level collection interface via the `collection` property: |
| 116 | + |
| 117 | +```diff |
| 118 | + const graphEdges = graph.edgeCollection("edges"); |
| 119 | +-const outEdges = graphEdges.outEdges("vertices/start"); |
| 120 | ++const outEdges = graphEdges.collection.outEdges("vertices/start"); |
| 121 | +``` |
| 122 | + |
| 123 | +### Cursor methods |
| 124 | + |
| 125 | +The method `each` is now called `forEach`. The method `hasNext` has been |
| 126 | +replaced with a getter. |
| 127 | + |
| 128 | +The methods `some` and `every` have been removed. These methods previously |
| 129 | +allowed iterating over cursor results in order to derive a boolean value by |
| 130 | +applying a callback function to each value in the result. |
| 131 | + |
| 132 | +In most cases these methods can be avoided by writing a more efficient AQL |
| 133 | +query: |
| 134 | + |
| 135 | +```diff |
| 136 | +-const cursor = await db.query(aql` |
| 137 | +- FOR bowl IN porridges |
| 138 | +- RETURN bowl |
| 139 | +-`); |
| 140 | +-const someJustRight = await cursor.some( |
| 141 | +- (bowl) => bowl.temperature < TOO_HOT && bowl.temperature > TOO_COLD |
| 142 | +-); |
| 143 | ++const cursor = await db.query(aql` |
| 144 | ++ FOR bowl IN porridges |
| 145 | ++ FILTER bowl.temperature < ${TOO_HOT} |
| 146 | ++ FILTER bowl.temperature > ${TOO_COLD} |
| 147 | ++ LIMIT 1 |
| 148 | ++ RETURN 1 |
| 149 | ++`); |
| 150 | ++const someJustRight = Boolean(await cursor.next()); |
| 151 | +``` |
| 152 | + |
| 153 | +If this is not an option, the old behavior can be emulated using the `forEach` |
| 154 | +method (previously called `each`) instead: |
| 155 | + |
| 156 | +```diff |
| 157 | +-const someJustRight = await cursor.some( |
| 158 | +- (bowl) => bowl.temperature < TOO_HOT && bowl.temperature > TOO_COLD |
| 159 | +-); |
| 160 | ++const someJustRight = !(await cursor.forEach( |
| 161 | ++ (bowl) => bowl.temperature === TOO_HOT || bowl.temperature === TOO_COLD |
| 162 | ++)); |
| 163 | +``` |
| 164 | + |
| 165 | +### Batch cursor API |
| 166 | + |
| 167 | +Cursors now provide a low-level API for iterating over the result batches |
| 168 | +instead of individual items, which is exposed via the `batches` property. |
| 169 | + |
| 170 | +The methods `hasMore` and `nextBatch` have been replaced with the getter |
| 171 | +`batches.hasMore` and the method `batches.next`: |
| 172 | + |
| 173 | +```diff |
| 174 | +-if (cursor.hasMore()) { |
| 175 | +- return await cursor.nextBatch(); |
| 176 | ++if (cursor.batches.hasMore) { |
| 177 | ++ return await cursor.batches.next(); |
| 178 | + } |
| 179 | +``` |
| 180 | + |
| 181 | +### Simple queries |
| 182 | + |
| 183 | +Collection methods for using simple queries (e.g. `all`, `any` and `list`) |
| 184 | +have been deprecated in ArangoDB 3.0 and are now also deprecated in arangojs. |
| 185 | + |
| 186 | +See the documentation of each method for an example for how to perform the same |
| 187 | +query using an AQL query instead. |
| 188 | + |
| 189 | +Additionally the `list` method now returns a cursor instead of an array. |
| 190 | + |
| 191 | +### ArangoSearch Views |
| 192 | + |
| 193 | +The database methods `arangoSearchView` and `createArangoSearchView` have been |
| 194 | +renamed to `view` and `createView` respectively as there currently is no other |
| 195 | +view type available in ArangoDB: |
| 196 | + |
| 197 | +```diff |
| 198 | +-await db.createArangoSearchView("my-view"); |
| 199 | +-const view = db.arangoSearchView("my-view"); |
| 200 | ++await db.createView("my-view"); |
| 201 | ++const view = db.view("my-view"); |
| 202 | +``` |
| 203 | + |
| 204 | +### Query options |
| 205 | + |
| 206 | +The `options` argument of `db.query` has been flattened. Options that were |
| 207 | +previously nested in an `options` property of that argument are now specified |
| 208 | +directly on the argument itself: |
| 209 | + |
| 210 | +```diff |
| 211 | + const cursor = await db.query( |
| 212 | + aql` |
| 213 | + FOR doc IN ${collection} |
| 214 | + RETURN doc |
| 215 | + `, |
| 216 | + { |
| 217 | + cache: false, |
| 218 | +- options: { fullCount: true }, |
| 219 | ++ fullCount: true, |
| 220 | + } |
| 221 | + ); |
| 222 | +``` |
| 223 | + |
| 224 | +### Bulk imports |
| 225 | + |
| 226 | +The default value of the `type` option now depends on the input type instead |
| 227 | +of always defaulting to `"auto"`. If you previously relied on the default |
| 228 | +value being set to `"auto"`, you may now need to explicitly set this option: |
| 229 | + |
| 230 | +```diff |
| 231 | +-await collection.import(data); |
| 232 | ++await collection.import(data, { type: "auto" }); |
| 233 | +``` |
| 234 | + |
| 235 | +### Bulk operations |
| 236 | + |
| 237 | +The collection method `bulkUpdate` has been removed and the methods |
| 238 | +`save`, `update`, `replace` and `remove` no longer accept arrays as input. |
| 239 | + |
| 240 | +Bulk operations can now be performed using the dedicated methods |
| 241 | +`saveAll`, `updateAll`, `replaceAll` and `removeAll`: |
| 242 | + |
| 243 | +```diff |
| 244 | +-await collection.save([{ _key: "a" }, { _key: "b" }]); |
| 245 | ++await collection.saveAll([{ _key: "a" }, { _key: "b" }]); |
| 246 | +``` |
| 247 | + |
| 248 | +### Cross-collection operations |
| 249 | + |
| 250 | +Collection methods no longer accept document IDs from other collections. |
| 251 | +Previously passing a document ID referring to a different collection would |
| 252 | +result in the collection performing a request to that collection instead. Now |
| 253 | +mismatching IDs will result in an error instead: |
| 254 | + |
| 255 | +```js |
| 256 | +const collection1 = db.collection("collection1"); |
| 257 | +const doc = await collection1.document("collection2/xyz"); // ERROR |
| 258 | +``` |
| 259 | + |
| 260 | +### Creating graphs |
| 261 | + |
| 262 | +The signatures of `db.createGraph` and `graph.create` have changed to always |
| 263 | +take an array of edge definitions as the first argument instead of taking the |
| 264 | +edge definitions as a property of the `properties` argument. |
| 265 | + |
| 266 | +Additionally the `properties` and `options` arguments have been merged: |
| 267 | + |
| 268 | +```diff |
| 269 | + await graph.create( |
| 270 | ++ [{ collection: "edges", from: ["a"], to: ["b"] }], |
| 271 | + { |
| 272 | +- edgeDefinitions: [{ collection: "edges", from: ["a"], to: ["b"] }], |
| 273 | + isSmart: true, |
| 274 | +- }, |
| 275 | +- { |
| 276 | + waitForSync: true, |
| 277 | + } |
| 278 | + ); |
| 279 | +``` |
| 280 | + |
| 281 | +### Transactions |
| 282 | + |
| 283 | +The transaction method `run` has been renamed to `step` to make it more obvious |
| 284 | +that it is intended to only perform a single "step" of the transaction. |
| 285 | + |
| 286 | +See the method's documentation for examples of how to use the method correctly. |
| 287 | + |
| 288 | +Additionally the method `transaction` no longer acts as an alias for |
| 289 | +`executeTransaction`: |
| 290 | + |
| 291 | +```diff |
| 292 | +-const result = await db.transaction(collections, action); |
| 293 | ++const result = await db.executeTransaction(collections, action); |
| 294 | +``` |
| 295 | + |
| 296 | +### Service development mode |
| 297 | + |
| 298 | +The methods `enableServiceDevelopmentMode` and `disableServiceDevelopmentMode` |
| 299 | +have been replaced with the method `setServiceDevelopmentMode`: |
| 300 | + |
| 301 | +```diff |
| 302 | +-await db.enableServiceDevelopmentMode("/my-foxx"); |
| 303 | ++await db.setServiceDevelopmentMode("/my-foxx", true); |
| 304 | +``` |
| 305 | + |
| 306 | +### System services |
| 307 | + |
| 308 | +The default value of the method `listServices` option `excludeSystem` has been |
| 309 | +changed from `false` to `true`: |
| 310 | + |
| 311 | +```diff |
| 312 | +-const services = await db.listServices(true); |
| 313 | ++const services = await db.listServices(); |
| 314 | +``` |
| 315 | + |
| 316 | +### Query tracking |
| 317 | + |
| 318 | +The method `setQueryTracking` has been merged into `queryTracking`: |
| 319 | + |
| 320 | +```diff |
| 321 | +-await db.setQueryTracking({ enabled: true }); |
| 322 | ++await db.queryTracking({ enabled: true }); |
| 323 | +``` |
| 324 | + |
| 325 | +### Collection properties |
| 326 | + |
| 327 | +The method `setProperties` has been merged into `properties`: |
| 328 | + |
| 329 | +```diff |
| 330 | +-await collection.setProperties({ waitForSync: true }); |
| 331 | ++await collection.properties({ waitForSync: true }); |
| 332 | +``` |
| 333 | + |
| 334 | +### View properties |
| 335 | + |
| 336 | +The View method `setProperties` has been renamed to `updateProperties`: |
| 337 | + |
| 338 | +```diff |
| 339 | +-await view.setProperties({ consolidationIntervalMsec: 234 }); |
| 340 | ++await view.updateProperties({ consolidationIntervalMsec: 234 }); |
| 341 | +``` |
| 342 | + |
| 343 | +### Truncating collections |
| 344 | + |
| 345 | +The `db.truncate` method has been removed. The behavior can still be mimicked |
| 346 | +using the `db.collections` and `collection.truncate` methods: |
| 347 | + |
| 348 | +```diff |
| 349 | +-await db.truncate(); |
| 350 | ++await Promise.all( |
| 351 | ++ db.collections().map((collection) => collection.truncate()) |
| 352 | ++); |
| 353 | +``` |
0 commit comments