{"id":13795456,"url":"https://github.com/StefanoMartin/ArangoRB","last_synced_at":"2025-05-12T23:32:20.097Z","repository":{"id":62553470,"uuid":"63786346","full_name":"StefanoMartin/ArangoRB","owner":"StefanoMartin","description":"A Gem for ArangoDB","archived":false,"fork":false,"pushed_at":"2020-02-08T19:03:01.000Z","size":433,"stargazers_count":40,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-26T22:05:47.288Z","etag":null,"topics":["arangodb","database"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StefanoMartin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-20T14:05:21.000Z","updated_at":"2023-07-21T23:32:34.000Z","dependencies_parsed_at":"2022-11-03T04:15:50.485Z","dependency_job_id":null,"html_url":"https://github.com/StefanoMartin/ArangoRB","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefanoMartin%2FArangoRB","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefanoMartin%2FArangoRB/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefanoMartin%2FArangoRB/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StefanoMartin%2FArangoRB/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StefanoMartin","download_url":"https://codeload.github.com/StefanoMartin/ArangoRB/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253840935,"owners_count":21972568,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arangodb","database"],"created_at":"2024-08-03T23:00:57.294Z","updated_at":"2025-05-12T23:32:19.775Z","avatar_url":"https://github.com/StefanoMartin.png","language":"Ruby","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"ArangoRB [![Gem Version](https://badge.fury.io/rb/arangorb.svg)](https://badge.fury.io/rb/arangorb)\n===============================\n\nUNMANTAINED: This project is not mantained anymore. A new Ruby ArangoDB driver project is in development here: [arango-driver](https://github.com/isomorfeus/arango-driver). Thank you a lot for your support in these years. \n\n[ArangoDatabase](https://www.arangodb.com/) is a native multi-model database with flexible data models for document, graphs, and key-values.\nArangoRB is a Gem to use ArangoDatabase with Ruby. ArangoRB is based on the [HTTP API of ArangoDB](https://docs.arangodb.com/3.4/HTTP/index.html).\n\nArangoRB 0.1.0 - 1.3.0 have been tested with ArangoDB 3.0  with Ruby 2.3.1\u003c/br\u003e\nArangoRB 1.4.0 has been tested with ArangoDB 3.1 with Ruby 2.3.3\u003c/br\u003e\nArangoRB 2.0.0 has been tested with ArangoDB 3.4 with Ruby 2.3.3\u003c/br\u003e\n\nIt requires the gems \"HTTParty\", \"Oj\" and \"connection_pool\"\u003c/br\u003e\n\nTo install ArangoRB: `gem install arangorb`\n\nTo use it in your application: `require \"arangorb\"`\n\n## Support\n\nThis is a project managed by one single person. ArangoDB is a wonderful project that it is hard to cover completely alone. For this reason all your supports is more than welcome.\nAny pull request, issue, suggestions and ideas are more than welcome. Do not be shy to contact me, create issues on Github or pushing changes.\n\nHere something the community can help on:\n* Replication example in example/replication_year.rb is a work in progress. Any found bugs and advice to improve it will be great. I removed the IPs in the examples to make clear that it is only an example that needs work.\n* Add test and correct bugs for replication, clustering, foxx and other.\n* Improve AQL instance to implement in Rails.\n* Improve Documentation.\n\nIf you like this project, please star it. It will remind me that my work has been useful for somebody.  \n\nFor the differences between version 1.4.0 and 2.0.0: [Click here](#differences).\n\nFor testing: [Click here](#testing).\n\n## Classes used\n\nArangoRB has the two type of classes.\n\nClasses relative to ArangoDB elements:\n* [Arango::Server](#ArangoServer): to manage a Server\n* [Arango::Database](#ArangoDatabase): to manage a Database\n* [Arango::Collection](#ArangoCollection): to manage a Collection\n* [Arango::Document](#ArangoDocument): to manage a Document\n* [Arango::Vertex](#ArangoVertex): to manage a Vertex\n* [Arango::Edge](#ArangoEdge): to manage an Edge\n* [Arango::Graph](#ArangoGraph): to manage a Graph\n* [Arango::Traversal](#ArangoTraversal): to manage a Traversal operation\n* [Arango::AQL](#arangoaql): to manage an AQL instances\n* [Arango::User](#ArangoUser): to manage an User\n* [Arango::Index](#ArangoIndex): to manage an Index\n* [Arango::Task](#ArangoTask): to manage a Task\n* [Arango::Transaction](#ArangoTransaction): to manage a Transaction\n* [Arango::Replication](#ArangoReplication): to manage a Replication\n* [Arango::Batch](#ArangoBatch): to manage a Batch of multiple requests\n* [Arango::Foxx](#ArangoFoxx): to manage a Foxx instance\n* [Arango::View](#ArangoView): to manage a View instance\n\nClasses relative to the Gem ArangoRB\n* [Arango::Cache](#ArangoCache): to manage internal Cache\n* [Arango::Error](#ArangoError): to handle ArangoRB errors\n\nAll the instances of these classes can be transformed in Hash with the method to_h.\n\nMany methods can have multiple attributes not mentioned in this documentation. Keep in mind that if an attribute is defined in the ArangoDB documentation, then it is easy that it is an attribute for the relative method too.\nPlease refer to the ArangoDB documentation, the rubydoc documentation or open an issue for this missing attributes.\n\n\u003ca name=\"ArangoServer\"\u003e\u003c/a\u003e\n## Arango::Server\n\nArango::Server is used to manage a single server by managing the connection with ArangoDB.\nYou can provide your login credentials and it is a mandatory step to start your database.\n\nTo setup a server use the following way:\n\n``` ruby\nserver = Arango::Server.new username: \"MyUsername\", password: \"MyPassword\",\n  server: \"localhost\", port: \"8529\", tls: false\nserver.username = \"MyOtherUsername\" # Default \"root\"\nserver.password = \"other_password\"  \nserver.server   = \"127.0.0.1\"       # Default \"localhost\"\nserver.port     = \"8765\"            # Default \"8529\"\nserver.tls      = true   # Default false, to do https requests instead of http\n```\n\nPassword is a mandatory field.\n\n### Returning results\n\nArangoRB try always to store the information obtained from ArangoDB in an instance.\nIf you need to receive the output, you can return it with:\n\n``` ruby\nserver.return_output = true # Default false\n```\n\n### Verbose and warnings\n\nFor Debugging reasons the user can print out the request and response to ArangoDB by setting verbose to true.\n\n``` ruby\nserver.verbose = true # Default false\n```\n\nRemember that verbose is only for testing reason: to work efficiently verbose should be false.\n\nSome deprecated methods will return a warning. To silence these warnings use:\n\n``` ruby\nserver.warning = false # Default true\n```\n\n### Connection Pool\n\nArangoRB supports connection pool, to activate it you can setup pool to true during the initialization or the proceedings. To do so use:\n\n``` ruby\nserver = Arango::Server.new username: \"MyUsername\", password: \"MyPassword\",\n  server: \"localhost\", port: \"8529\", pool: true, size: 5, timeout: 5, tls: false\nserver.pool = true  # Defult false\nserver.size = 7     # Default 5\nserver.timeout = 10 # Default 5\nserver.restartPool  # Restart pool with new size and timeout\n```\n\nNB: ConnectionPool is not heavily tested.\n\n### Cache\n\nOften ArangoRB returns multiple time the same object (for example for lists or for retrieving). It can happens thus that a document instance updated somewhere in your code, it is not update somewhere even if you are refering the same ArangoDB document.\nTo avoid this, ArangoRB provides its own cache.\n\nYou can activate the ArangoRB cache by using:\n\n``` ruby\nserver.active_cache = true # Default false\n```\n\nIf active_cache is true, then a previous document or collection instance will be stored in the ArangoRB cache. In case a new instance of the same document is created, then a new instance will NOT be created but, instead, the old one will be returned.\n\nWith an example:\n\n``` ruby\nserver.active_cache = false\na = Arango::Document.new name: \"test\", collection: my_collection\nb = Arango::Document.new name: \"test\", collection: my_collection\n# In this case a and b are two different instances\n```\n\n``` ruby\nserver.active_cache = true\na = Arango::Document.new name: \"test\", collection: my_collection\nb = Arango::Document.new name: \"test\", collection: my_collection\n# In this case a and b are the same instance\n```\n\nNote that if you set server.active_cache to false, then the stored Cache will be emptied.\nFor more information about the cache, look at the section about [Arango::Cache](#ArangoCache).\n\n### Information\n\nBasic information can be retrieved with these command.\n\n``` ruby\nserver.to_h      # Return an hash of the instances\nserver.endpoint  # Check address used to connect with the server\nserver.username  # Check name used to connect with the server\nserver.verbose   # Check if verbose is true or false\nserver.async     # Check the status of async\n```\n\nTo retrieve lists\n\n``` ruby\nserver.databases # Lists of available databases\nserver.endpoints # Lists of endpoints used\nserver.users     # Lists of available users\nserver.tasks     # Lists of available tasks\n```\n\nTo monitoring the server you can use the following commands\n\n``` ruby\nserver.log # Return log files\nserver.loglevel\nserver.updateLoglevel body: body\nserver.available?    # Reloads the routing information from the collection routing.\nserver.reload        # Reloads the routing information from the collection routing.\nserver.statistics    # Returns the statistics information\nserver.statisticsDescription # Fetch descriptive info of statistics\nserver.status     # Status of the server\nserver.role       # Get to know whether this server is a Coordinator or DB-Server\nserver.serverData # Get server data\nserver.mode       # Get server mode\nserver.updateMode(mode: \"default\") # Change mode of the server\n```\n\n### Manage Async\n\nWith Arango::Server you can manage Async results. It can be useful to use async for heavy requests (like the one in example/year.rb).\n\n``` ruby\nserver.async = false  # default\nserver.async = true   # fire and forget\nserver.async = :store # fire and store\n```\n\nIf Async is \"store\", then the commands of ArangoRB will return the id of the Async requests.\nArango::Server provides different methods to manage these Async requests.\n\n``` ruby\nserver.fetchAsync    id: id # Fetches a job result and removes it from the queue\nserver.cancelAsync   id: id # Cancels an async job\nserver.destroyAsync  id: id # Deletes an async job result\nserver.retrieveAsync id: id # Returns the status of a specific job\nserver.retrieveAsyncByType type: type # Returns the ids of job results with a specific\n# status. Type can be \"done\" or \"pending\"\nserver.retrieveDoneAsync       # Equivalent to server.retrieveAsync type: \"done\"\nserver.retrievePendingAsync    # Equivalent to server.retrieveAsync type: \"pending\"\nserver.destroyAsync type: type # Deletes async jobs with a specific status\n                               # Type can be \"all\" or \"expired\"\nserver.destroyAllAsync         # Equivalent to server.destroyAsync type: \"all\"\nserver.destroyExpiredAsync     # Equivalent to server.destroyAsync type: \"expired\"\n```\n\n### Miscellaneous\n\n``` ruby\nserver.version           # Returns the server version number\nserver.engine            # Returns the server engine\nserver.flushWAL          # Flushes the write-ahead log\nserver.propertyWAL       # Retrieves the configuration of the write-ahead log\nserver.changePropertyWAL # Configures the write-ahead log\nserver.transactions      # Returns information about the currently running transactions\nserver.time              # Get the current time of the system\nserver.echo              # Return current request\nserver.databaseVersion   # Return the required version of the database\nserver.shutdown          # Initiate shutdown sequence\n```\n\nUNTESTED\n\n``` ruby\nserver.test body: body    # Runs tests on server\nserver.execute body: body # Execute a script on the server.\n```\n\n### Cluster (UNTESTED)\n\nArangoDB permits the sharding of the database. Although these methods has not been tested with ArangoRB.\n\n``` ruby\nserver.clusterHealth port: port # Allows to check whether a given port is usable\nserver.serverId                 # Returns the id of a server in a cluster.\nserver.clusterStatistics dbserver: dbserver # Allows to query the statistics of a\n                                            # DBserver in the cluster\n```\n\n\u003ca name=\"ArangoDatabase\"\u003e\u003c/a\u003e\n## Arango::Database\n\nArango::Database is used to manage a Database. You can create an instance in one of the following ways:\n\n``` ruby\nmyDatabase = server.database name: \"MyDatabase\"\nmyDatabase = server[\"MyDatabase\"]\nmyDatabase = Arango::Database.new database: \"MyDatabase\", server: server\n```\n\n### Main methods\n\n``` ruby\nmyDatabase.create   # Create a new Database\nmyDatabase.retrieve # Retrieve database\nmyDatabase.destroy   # Delete the selected Database\n```\n\n### Retrieve information\n\n``` ruby\nserver.databases       # Obtain an Array with the available databases in the server\nmyDatabase.to_h        # Hash of the instance\nmyDatabase.info        # Obtain general info about the databases\nmyDatabase.sever       # Return the server connected with the database\nmyDatabase.collections # Obtain an Array with the available collections in the selected Database\nmyDatabase.graphs       #  Obtain an Array with the available graphs in the selected Database\nmyDatabase.aqlFunctions #  Obtain an Array with the available functions in the selected Database\nmyDatabase.foxxes # Return all the foxx available in the database\nmyDatabase.views  # Return all the views available in the database\nmyDatabase.tasks  # Return all the tasks available in the database\n```\n\n\u003ca name=\"arangoaql\"\u003e\u003c/a\u003e\n## Arango::AQL\n\nAn AQL instance can be created by using one of the following way:\n\n``` ruby\nquery = \"FOR v,e,p IN 1..6 ANY 'Year/2016' GRAPH 'MyGraph' FILTER p.vertices[1].num == 6 \u0026\u0026 p.vertices[2].num == 22 \u0026\u0026 p.vertices[6]._key == '424028e5-e429-4885-b50b-007867208c71' RETURN [p.vertices[4].value, p.vertices[5].data]\"\nmyQuery = myDatabase.aql query: query\nmyQuery = ArangoAQL.new database: myDatabase, query: query\n```\n\nTo execute it use:\n\n``` ruby\nmyQuery.execute\n```\n\nIf the query is too big, you can divide the fetching in pieces, for example:\n\n``` ruby\nmyQuery.size = 10\nmyQuery.execute # First 10 documents\nmyQuery.next    # Next 10 documents\nmyQuery.next    # Next 10 documents\n```\n\nOther useful methods are the following\n\n``` ruby\nmyQuery.destroy # Destroy cursor to retrieve documents\nmyQuery.kill    # Kill query request (if requires too much time)\nmyQuery.explain # Show data query\nmyQuery.parse   # Parse query\n```\n\n### Query Properties\n\nIt is possible to handle generic properties of query by Arango::Database.\n\n``` ruby\nmyQuery.to_h                                # Return an hash version of the instance\nmyQuery.properties                          # Check Query properties\nmyQuery.current                             # Retrieve current running Query\nmyQuery.changeProperties maxSlowQueries: 65 # Change Properties\nmyQuery.slow                                # Retrieve slow Queries\nmyQuery.stopSlowQueries                     # Stop slow Queries\n```\n\nThe cache of the query can handle in the following way:\n\n``` ruby\nmyDatabase.retrieveQueryCache                      # Retrieve Query Cache\nmyDatabase.clearQueryCache                         # Clear Query Cache\nmyDatabase.propertyQueryCache                      # Check properties Cache\nmyDatabase.changePropertyQueryCache maxResults: 30 # Change properties Cache\n```\n\n### AQL Functions\n\nAQL queries can be potentiate by providing javascript function as supports.\n\n``` ruby\nmyDatabase.createAqlFunction code: \"function(){return 1+1;}\", name: \"myFunction\" # Create a new AQL Function\nmyDatabase.deleteFunction name: \"myFunction\" # Delete an AQL function\nmyDatabase.aqlFunctions # Retrieve a list of the available aql functions\n```\n\n\u003ca name=\"ArangoCollection\"\u003e\u003c/a\u003e\n## Arango::Collection\n\nArango::Collection is used to manage your Collections. You can create an Arango::Collection instance in one of the following way:\n\n``` ruby\nmyCollection = myDatabase.collection name: \"MyCollection\"\nmyCollection = myDatabase[\"MyCollection\"]\nmyCollection = Arango::Collection.new database: myDatabase, collection: \"MyCollection\"\n```\n\nA Collection can be of two types: \"Document\" and \"Edge\". If you want to specify it, uses:\n\n``` ruby\nmyCollectionA = ArangoCollection.new collection: \"MyCollectionA\", type: :document # Default\nmyEdgeCollection = ArangoCollection.new collection: \"MyCollectionB\", type: :edge\n```\n\n### Main methods\n\n``` ruby\nmyCollection.create   # Create collection\nmyCollection.destroy  # Delete collection from database\nmyCollection.truncate # Delete all the Documents inside the selected Collection\nmyCollection.retrieve # Retrieve the selected Collection\n```\n\n### Info methods\n\n``` ruby\nmyCollection.database   # Return database of the collection\nmyCollection.server     # Returm server of the collection\nmyCollection.indexes    # Return a list of all used Indexes in the Collection\nmyCollection.rotate     # Rotate the collection\nmyCollection.data       # Returns the whole content of one collection\nmyCollection.properties # Properties of the Collection\nmyCollection.count      # Number of Documents in the Collection\nmyCollection.stats      # Statistics of the Collection\nmyCollection.revision   # Return collection revision id\nmyCollection.checksum   # Return checksum for the Collection\n```\n\n### Modify the Collection\n\n``` ruby\nmyCollection.load   # Load the collection (preparing for retrieving documents)\nmyCollection.unload # Unload the collection (if you stop to work with it)\nmyCollection.loadIndexesIntoMemory            # Load indexes in memory\nmyCollection.change(waitForSync: true)        # Change some properties\nmyCollection.rename(newName: \"myCollection2\") # Change name (NB: This is not Arango::Cache compatible)\nmyCollection.rotate # Rotate journal of a collection\n```\n\n### Handle documents\n\nTo retrieve all the documents of a Collection you can use:\n\n``` ruby\nmyCollection.documents\nmyCollection.allDocuments\n```\n\nThese two functions are similar except for the fact that you can assign different variables.\n\n``` ruby\nmyCollection.documents type: \"path\"\nmyCollection.next # Retrieve other documents if the first request is not finished\n```\n\nType can be \"path\", \"id\" or \"key\" in relation what we wish to have. If not specified ArangoRB will return an array of Arango::Document instances.\n\n``` ruby\nmyCollection.allDocuments skip: 3, limit: 100, batchSize: 10\n```\n\nIt means that we skip the first three Documents, we can retrieve the next 100 Documents but we return only the first ten.\n\nTo retrieve specific Document you can use:\n\n``` ruby\nmyCollection.documentsMatch match: {\"value\":  4}   # All Documents of the Collection with value equal to 4\nmyCollection.documentMatch match: {\"value\":  4}    # The first Document of the Collection with value equal to 4\nmyCollection.documentByKeys keys: [\"4546\", \"4646\"] # Documents of the Collection with the keys in the Array\nmyCollection.documentByName names: [\"4546\", \"4646\"] # Documents of the Collection with the name in the Array\nmyCollection.random # A random Document of the Collection\n```\n\n#### Modifying multiple documents\n\nFrom a collection is it possible to create, remove and modify multiple documents.\n\n``` ruby\nmyCollection.createDocuments document: [myDocumentA, myDocumentB, {\"value\":  17}] # Array of Arango::Document instances and Hashes\nmyCollection.removeByKeys keys: [\"4546\", \"4646\"] # Documents of the Collection with the keys in the Array will be removed\nmyCollection.removeMatch match: {\"value\":  4} # All Documents of the Collection with value equal to 4 will be removed\nmyCollection.replaceMatch match: {\"value\":  4}, newValue: {\"value\":  6} # All Documents of the Collection with value equal to 4 will be replaced with the new Value\nmyCollection.updateMatch match: {\"value\":  4}, newValue: {\"value\":  6} # All Documents of the Collection with value equal to 4 will be updated with the new Value\n```\n\n#### Create multiple Edges at once\n\nWe have the possibility to create different combination of Edges in only one line of code.\n\nOne-to-one with one Edge class\n\n * [myDocA] --(myEdge)--\u003e [myDocB]\n\n``` ruby\nmyEdgeCollection.createEdges document: myEdge, from: myDocA, to: myDocB\n```\n\nOne-to-more with one Edge class (and More-to-one with one Edge class)\n\n * [myDocA] --(myEdge)--\u003e [myDocB]\n * [myDocA] --(myEdge)--\u003e [myDocC]\n\n ``` ruby\nmyEdgeCollection.createEdges document: myEdge, from: myDocA, to: [myDocB, myDocC]\n```\n\nMore-to-More with one Edge class\n\n * [myDocA] --(myEdge)--\u003e [myDocC]\n * [myDocB] --(myEdge)--\u003e [myDocC]\n * [myDocA] --(myEdge)--\u003e [myDocD]\n * [myDocB] --(myEdge)--\u003e [myDocD]\n\n ``` ruby\nmyEdgeCollection.createEdges document: myEdge, from: [myDocA, myDocB], to: [myDocC, myDocD]\n```\n\nMore-to-More with more Edge classes\n\n * [myDocA] --(myEdge)--\u003e [myDocC]\n * [myDocB] --(myEdge)--\u003e [myDocC]\n * [myDocA] --(myEdge)--\u003e [myDocD]\n * [myDocB] --(myEdge)--\u003e [myDocD]\n * [myDocA] --(myEdge2)--\u003e [myDocC]\n * [myDocB] --(myEdge2)--\u003e [myDocC]\n * [myDocA] --(myEdge2)--\u003e [myDocD]\n * [myDocB] --(myEdge2)--\u003e [myDocD]\n\n``` ruby\nmyEdgeCollection.createEdges document: [myEdge, myEdge2], from: [myDocA, myDocB], to: [myDocC, myDocD]\n```\n\n\n### Import and Export Documents\n\nAnother way to create multiple documents in a Collection with only one request is by using the method import.\n\n#### Import one Document with Array\n\nWe can import one document with the following structure {\"value\": \"uno\", \"num\": 1, \"name\": \"ONE\"}.\n\n``` ruby\nattributes = [\"value\", \"num\", \"name\"]\nvalues     = [\"uno\",1,\"ONE\"]\nmyCollection.import attributes: attributes, values: values\n```\n\n#### Import more Documents with Array\n\nWe can import three Documents with the following structure {\"value\": \"uno\", \"num\": 1, \"name\": \"ONE\"}, {\"value\": \"due\", \"num\": 2, \"name\": \"TWO\"}, {\"value\": \"tre\", \"num\": 3, \"name\": \"THREE\"}.\n\n``` ruby\nattributes = [\"value\", \"num\", \"name\"]\nvalues     = [[\"uno\",1,\"ONE\"],[\"due\",2,\"TWO\"],[\"tre\",3,\"THREE\"]]\nmyCollection.import attributes: attributes, values: values\n```\n\n#### Import more Documents with JSON\n\nI import two Documents with the following structure {\"value\": \"uno\", \"num\": 1, \"name\": \"ONE\"}, {\"value\": \"due\", \"num\": 2, \"name\": \"TWO\"}.\n\n``` ruby\nbody = [{\"value\": \"uno\", \"num\": 1, \"name\": \"ONE\"}, {\"value\": \"due\", \"num\": 2, \"name\": \"DUE\"}]\nmyCollection.importJSON body: body\n```\n\n#### Export files\n\nAs it is possible to import files, it is possible to export all the Document of a Collection with the following command.\n\n``` ruby\nmyCollection.export\n```\n\nAlternatively it is possible to retrieve all the Documents in a Collection gradually.\n\n``` ruby\nmyCollection.export batchSize: 3 # First three Documents of the Collection\nmyCollection.exportNext # Next three Documents\nmyCollection.exportNext # Next three Documents\n```\n\n\u003ca name=\"ArangoDocument\"\u003e\u003c/a\u003e\n## Arango::Document\n\nAn Arango::Document is an element of a Arango::Collection. Edges are Arango documents with \"\\_from\" and \"\\_to\" in their body.\nYou can create an ArangoCollection instance in one of the following way:\n\n``` ruby\nmyDocument = myCollection.document name: \"MyDocument\"\nmyDocument = myCollection[\"MyDocument\"]\nmyDocument = Arango::Document.new collection: myCollection, name: \"MyDocument\"\n```\n\nIn the case you want to define a Edge, it is convenient to introduce the parameters \"from\" and \"to\" in the instance.\n\n``` ruby\nmyEdge = Arango::Document.new name: \"MyEdge\", from: myDocA, to: myDocB\n```\n\nwhere myDocA and myDocB are the IDs of two Documents or are two Arango::Document instances.\n\nDuring the creation of an Arango::Document instance, it is possible to define the body for the Document.\n\n``` ruby\nmyDocument = Arango::Document.new body: {\"value\":  17}, name: \"MyDocument\"\n```\n\n### Main methods\n\nArangoRB provides several way to create a single Document.\n\n``` ruby\nmyDocument.create                      # Create a new document\nmyDocument.retrieve                    # Retrieve Document\nmyDocument.update body: {\"value\":  3}  # We update or add a value\nmyDocument.replace body: {\"value\":  3} # We replace a value\nmyDocument.destroy                     # Destroy document\n```\n\n### Retrieve information\n\n``` ruby\nmyDocument.collection # Retrieve Collection of the Document\nmyDocument.database   # Retrieve Database of the Document\nmyDocument.server     # Retrieve Server of the Document\nmyDocument.edges collection: myEdgeCollection  # Retrieve all myEdgeCollection edges connected with the Document\nmyDocument.any(myEdgeCollection) # Retrieve all myEdgeCollection edges connected with the Document\nmyDocument.in(myEdgeCollection)  # Retrieve all myEdgeCollection edges coming in the Document\nmyDocument.out(myEdgeCollection) # Retrieve all myEdgeCollection edges going out the Document\nmyEdge.from # Retrieve the document at the begin of the edge\nmyEdge.to   # Retrieve the document at the end of the edge\n```\n\n#### Example: how to navigate the edges\n\nIt is possible to navigate between edges and vertexes of a graph database.\n\nThink for example that we have the following schema:\n * A --[class: a, name: aa]--\u003e B\n * A --[class: a, name: bb]--\u003e C\n * A --[class: b, name: cc]--\u003e D\n * B --[class: a, name: dd]--\u003e E\n\nThen we have:\n\n * A.retrieve is A\n * A.edges(collection: a) is [aa, bb]\n * B.in(a) is [aa]\n * B.out(a) is [dd]\n * B.any(a) is [aa, dd] (aa in entry, dd in exit)\n * aa.from is A\n * aa.to is B\n\nWe can even do some combinations: for example A.out(a)[0].to.out(a)[0].to is E since:\n * A.out(a) is [aa]\n * A.out(a)[0] is aa\n * A.out(a)[0].to is B\n * A.out(a)[0].to.out(a) is [dd]\n * A.out(a)[0].to.out(a)[0] is dd\n * A.out(a)[0].to.out(a)[0].to is E\n\n\u003ca name=\"ArangoGraph\"\u003e\u003c/a\u003e\n## Arango::Graph\n\nArangoGraph are used to manage Graphs. You can create an Arango::Graph instance in one of the following way.\n\n``` ruby\nmyGraph = myDatabase.graph name: \"MyGraph\"\nmyGraph = Arango::Graph.new name: \"MyGraph\", database: myDatabase\n```\n\n### Main methods\n\n``` ruby\nmyGraph.create   # create a new Graph\nmyGraph.retrieve # retrieve the Graph\nmyGraph.database # retrieve database of the Graph\nmyGraph.destroy  # destroy the Graph\n```\n\n### Manage Vertex Collections\n\n``` ruby\nmyGraph.getVertexCollections # Retrieve all the vertexCollections of the Graph\nmyGraph.addVertexCollection collection: \"myCollection\"  # Add a Vertex Collection to our Graph\nmyGraph.removeVertexCollection collection: \"myCollection\"  # Remove a Vertex Collection to our Graph\n```\n\n### Manage Edge Collections\n\n``` ruby\nmyGraph.edgeCollections # Retrieve all the edgeCollections of the Graph\nmyGraph.addEdgeCollections collection: \"myEdgeCollection\", from: \"myCollectionA\", to: \"myCollectionB\"  # Add an Edge Collection to our Graph\nmyGraph.replaceEdgeCollections collection: \"myEdgeCollection\", from: \"myCollectionA\", to: \"myCollectionB\"  # Replace an Edge Collection to our Graph\nmyGraph.removeEdgeCollections collection: \"myEdgeCollection\"  # Remove an Edge Collection to our Graph\n```\n\n\u003ca name=\"ArangoVertex\"\u003e\u003c/a\u003e\n\u003ca name=\"ArangoEdge\"\u003e\u003c/a\u003e\n## Arango::Vertex and Arango::Edge\n\nBoth these two classes inherit the class Arango::Document.\nThese two classes have been created since Arango::Database offers, in connection of the chosen graph, different HTTP requests to manage Vertexes and Edges. We recommend the reader to read carefully the section on [Arango::Document instances](#ArangoDocument) before to start to use Arango::Vertex and Arango::Edge instances.\n\n### Arango::Vertex methods\n\nArango::Vertex inherit all the methods of Arango::Document class. The following one works similar to the one of Arango::Document Class but use different HTTP requests. For this reason the performance could be different.\nTo use Arango::Vertex, the Collection of the Vertex needs to be added either to the VertexCollections or to the EdgeCollections of the chosen Graph. And the Collection needs to have assigned the graph.\n\n``` ruby\nmyCollection.graph = myGraph # Be sure that the collection is assigned to a Graph\nmyVertex = myCollection.vertex name: \"newVertex\", body: {\"value\":  3} # If graph is not assigned, an Arango::Document will be created\nmyVertex = Arango::Vertex.new name: \"newVertex\", body: {\"value\":  3},\n  collection: myCollection # create a new instance\n```\n\n```   ruby\nmyVertex.create    # create a new Document in the Graph\nmyVertex.retrieve  # retrieve a Document\nmyVertex.graph     # retrieve Graph of the Document\nmyVertex.replace body: {\"value\":  6} # replace the Document\nmyVertex.update  body: {\"value\":  6} # update the Document\nmyVertex.destroy   # delete the Document\n```\n\n### Arango::Edge methods\n\nArango::Edge inherit all the methods of Arango::Document class. The following one works similar to the one of Arango::Document Class but use a different HTTP request. For this reason the performance could be different.\nTo use Arango::Edge, the Collection of the Edge needs to be added to the EdgeCollections of the chosen Graph.\n\n``` ruby\nmyEdgeCollection.graph = myGraph\nmyEdge = myCollection.edge name: \"newEdge\", body: {\"value\":  3}, from: myArangoDocument1, to: myArangoDocument2 # If graph is not assigned, an Arango::Document will be created\n```\n\n```   ruby\nmyEdge.create   # create a new Document of type Edge in the Graph\nmyEdge.retrieve # retrieve a Document\nmyEdge.graph    # Retrieve Graph  of the Document\nmyEdge.replace body: {\"value\":  6} # replace the Document\nmyEdge.update  body: {\"value\":  6} # update the Document\nmyEdge.destroy  # delete the Document\n```\n\n\u003ca name=\"ArangoTraversal\"\u003e\u003c/a\u003e\n## Arango::Traversal\n\nArango::Traversal is used to administrate the traversals.\nArango::Traversal needs to know the vertex from where the traversal starts, the direction the traversal is going and either the Graph or the EdgeCollection we want to analyze.\n\n\n``` ruby\nmyTraversal = myVertex.traversal   # Start traversal from myVertex\nmyTraversal = myDocument.traversal # Start traversal from myDocument\nmyTraversal = ArangoTraversal.new database: myDatabase, startVertex: myVertex # create instance\n```\n\n``` ruby\nmyTraversal.vertex = myVertex # define starting Vertex\nmyTraversal.edgeCollection = myEdgeCollection # define used Edge\nmyTraversal.in      # Direction is in\nmyTraversal.out     # Direction is out\nmyTraversal.any     # Direction is in and out\nmyTraversal.min = 1 # Define how minimum deep we want to go with the traversal\nmyTraversal.max = 3 # Define how maximum deep we want to go with the traversal\n```\n\nAfter the traversal is setup, you can execute it:\n\n``` ruby\nmyTraversal.execute\n```\n\n\u003ca name=\"ArangoUser\"\u003e\u003c/a\u003e\n## Arango::User\n\nArango::User manages the users.\nTo initialize an user:\n\n``` ruby\nmyUser = server.user name: \"MyUser\", password: \"password\"\nmyUser = Arango::User.new user: \"MyUser\", password: \"password\", server: server\n```\n\n### User management\n\n``` ruby\nmyUser.retrieve               # Retrieve User\nmyUser[\"MyDatabase\"]          # Retrieve database if the user can access it\nmyUser.database(\"MyDatabase\") # Retrieve database if the user can access it\nmyUser.create                 # Create a new User\nmyUser.replace active: false  # Replace User\nmyUser.update active: false   # Update User\nmyUser.destroy               # Delete User\n```\n\n### Database management\n\n``` ruby\nmyUser.databases # List of databases can access\nmyUser.addDatabaseAccess grant: \"rw\", database: myDatabase\nmyUser.grant          database: myDatabase # Grant access to a database\nmyUser.revoke         database: myDatabase # Revoke access to a database\nmyUser.databaseAccess database: myDatabase # Check permission level of an User\nmyUser.addCollectionAccess grant: \"rw\", database: myDatabase, collection: myCollection\nmyUser.revokeCollectionAccess database: myDatabase, collection: myCollection\nmyUser.collectionAccess database: myDatabase, collection: myCollection\n```\n\nYou can manage the user permissions from the database or from the collection too.\n\n``` ruby\nmyDatabase.check_user(myUser)\nmyDatabase.addUserAccess(grant: \"rw\", user: myUser)\nmyDatabase.revokeUserAccess(user: myUser)\nmyDatabase.userAccess(user: myUser)\nmyCollection.check_user(myUser)\nmyCollection.addUserAccess(grant: \"rw\", user: myUser)\nmyCollection.revokeUserAccess(user: myUser)\nmyCollection.userAccess(user: myUser)\n```\n\n\u003ca name=\"ArangoIndex\"\u003e\u003c/a\u003e\n## Arango::Index\n\nArango::Index manages the indexes.\nTo initialize an index:\n\n``` ruby\nmyIndex = myCollection.index fields: \"num\", unique: false, id: \"myIndex\"\nmyIndex = Arango::Index.new  fields: \"num\", unique: false, id: \"myIndex\", collection: myCollection\n```\n\n### Index management\n\n``` ruby\nmyIndex.retrieve # Retrieve Index\nmyIndex.create # Create a new Index\nmyIndex.destroy # Delete Index\n```\n\n\u003ca name=\"ArangoTransaction\"\u003e\u003c/a\u003e\n## Arango::Transaction\n\nTransactions are managed by Arango::Transaction.\n\n``` ruby\naction = \"function(){ var db = require('@arangodb').db; db.MyCollection.save({}); return db.MyCollection.count(); }\"\nmyTransaction = myDatabase.transaction action: action\nmyTransaction = Arango::Transaction.new action: action, database: myDatabase\n```\n\n``` ruby\nmyTransaction.addWrite(myCollection) # Add write collection\nmyTransaction.addRead(myCollection) # Add read collection\nmyArangoTransaction.execute # Return the result of the execution\n```\n\n\u003ca name=\"ArangoTask\"\u003e\u003c/a\u003e\n## Arango::Task\n\nTasks are managed by ArangoTask.\n\n``` ruby\ncommand = \"(function(params) { require('@arangodb').print(params); })(params)\"\nmyTask = myDatabase.task id: \"mytaskid\", name: \"MyTaskID\", command: command, params: {\"foo\":  \"bar\", \"bar\":  \"foo\"}, period: 2\nmyTask = Arango::Task.new id: \"mytaskid\", name: \"MyTaskID\", command: command, params: {\"foo\":  \"bar\", \"bar\":  \"foo\"}, period: 2, database: myDatabase\n```\n\n``` ruby\nmyArangoTask.create   # Create a new Task\nmyArangoTask.retrieve # Retrieve a Task\nmyArangoTask.destroy  # Delete a Task\n```\n\n\u003ca name=\"ArangoReplication\"\u003e\u003c/a\u003e\n## Arango::Replication\n\nReplication is useful to create back up copy of your database or to have a master-slave relationship between two databases.\n\nRemember: the used database is the one where the data will be written (the slave) and the remote database will be the master one.\n\nUse with caution since the data in the slave database will be deleted.\n\nTo setup our Slave Server and Master Database use a similar command.\n\n``` ruby\nmyReplication = slaveDatabase.replication(master: masterDatabase)\nmyReplication = masterDatabase.replication_as_master(slave: slaveDatabase)\nmyReplication = Arango::Replication.new master: masterDatabase, slave: slaveDatabase\n```\n\nThan to do a simple syncronization uses;\n\n``` ruby\nmyReplication.sync    # Sync master - slave database\n```\n\nTo retrieve other information ArangoRB provides the following methods:\n\n``` ruby\nmyReplication.logger       # Returns the current state of the server's replication logger\nmyReplication.loggerFollow # Returns data from the server's replication log.\nmyReplication.firstTick    # Return the first available tick value from the server\nmyReplication.rangeTick # Returns the currently available ranges of tick values for all currently available WAL logfiles.\nmyReplication.serverId  # Returns the servers id.\n```\n\n### Relation Master-Slave\n\nTo enslave a Server in relation to another Database use the following command:\n\n``` ruby\nmyReplication.enslave\n```\n\nTo manage the Configuration of a Master-Slave Replication you can use the following commands:\n\n``` ruby\nmyReplication.start   # Start replication\nmyReplication.configuration # check the Configuration of the Replication\nmyReplication.state   # check the status of the Replication\nmyReplication.stop    # stop the Replication\nmyReplication.modify  # modify the Configuration of the Replication (you can modify only a stopped Replication)\n```\n\n## Arango::Batch\n\nTo create a batch request, you can use ArangoRB::Batch object. This permit to do multiple requests with one single call to the API.\n\nTo create a batch use one of the following way:\n\n``` ruby\nbatch = server.batch\nbatch = Arango::Batch.new(server: server)\n```\n\nTo add a queries to the batch request you can use the brutal way:\n\n``` ruby\nbatch.queries = [\n  {\n    \"type\": \"POST\",\n    \"address\": \"/_db/MyDatabase/_api/collection\",\n    \"body\": {\"name\": \"newCOLLECTION\"},\n    \"id\": \"1\"\n  },\n  {\n    \"type\": \"GET\",\n    \"address\": \"/_api/database\",\n    \"id\": \"2\"\n  }\n]\n```\n\nOr the Ruby way (the id will be handled by the system, if not specified):\n\n``` ruby\nbatch = server.batch\nbatch.addQuery(method: \"POST\", address: \"/_db/MyDatabase/_api/collection\",\n  body: {\"name\": \"newCOLLECTION\"})\nbatch.addQuery(method: \"GET\", address: \"/_api/database\")\n```\n\nIn both the cases the queries will be stored in an hash with key the id of the query and as value the query.\nThis query can be handled with the following methods:\n\n``` ruby\nbatch.to_h # Retrieve an hash version of the instance\nbatch.modifyQuery(id: \"1\", method: \"GET\", address: \"/_db/MyDatabase/_api/collection/newCOLLECTION\") # Modify the Query with id \"1\"\nbatch.removeQuery(id: \"1\") # Remove query\n```\n\nTo execute the query use:\n\n``` ruby\nbatch.execute\n```\n\nTo manage how the server handle the batch, Arango::Server offers the following functions:\n\n``` ruby\nserver.createDumpBatch ttl: 10 # Create a new dump batch with 10 second time-to-live (return id of the dumpBatch)\nserver.prolongDumpBatch id: idDumpBatch, ttl: 20 # Prolong the life of a batch for 20 seconds\nserver.destroyDumpBatch id: idDumpBatch # Delete a selected batch\n```\n\n\u003ca name=\"ArangoView\"\u003e\u003c/a\u003e\n## Arango::View\n\nViews are managed by Arango::View.\n\n``` ruby\nmyView = myDatabase.view name: \"MyView\"\nmyView = Arango::View.new name: \"MyView\", database: myDatabase\n```\n\n``` ruby\nmyView.addLink(collection: myCollection) # Add a collection to the link\nmyView.retrieve               # Retrieve view\nmyView.create                 # Create a view\nmyView.replaceProperties      # Replace properties\nmyView.updateProperties       # Update properties\nmyView.rename name: \"MyView2\" # Change name\nmyView.properties             # Check properties\nmyView.destroy                # Delete view\n```\n\n\u003ca name=\"ArangoFoxx\"\u003e\u003c/a\u003e\n## Arango::Foxx\n\nViews are managed by Arango::Foxx. This instance of Foxx is untested.\n\n``` ruby\nmyFoxx = myDatabase.foxx mount: address\nmyFoxx = Arango::Foxx.new mount: address, database: myDatabase\n```\n\n``` ruby\nmyFoxx.retrieve # Retrieve foxx\nmyView.create   # Create a foxx\nmyFoxx.update   # Update foxx\nmyFoxx.replace  # Replace foxx\nmyFoxx.destroy  # Delete foxx\n```\n\nOther methods\n\n``` ruby\nmyFoxx.retrieveConfiguration\nmyView.updateConfiguration body: body\nmyFoxx.replaceConfiguration body: body\nmyFoxx.retrieveDependencies\nmyFoxx.updateDependencies body: body\nmyFoxx.replaceDependencies body: body\nmyFoxx.scripts\nmyFoxx.run_script name: \"test\"\nmyFoxx.tests\nmyFoxx.enableDevelopment\nmyFoxx.disableDevelopment\nmyFoxx.readme\nmyFoxx.swagger\nmyFoxx.download path: path\nmyFoxx.commit body: body\n```\n\n\u003ca name=\"ArangoCache\"\u003e\u003c/a\u003e\n## Arango::Cache\n\nArango::Cache is to manage ArangoRB Cache (NOT ArangoDB cache) and it helps you to manage your documents around your code. In this way if you update an Arango::Document in your code, it will updated everywhere.\nAn Arango::Cache instance is created together with the initialization of a server instance with active_cache true.\n\n``` ruby\ncache = server.cache # Arango::Cache instance\ncache.max            # Max number of variable stored in the cache\ncache.updateMax(type: :document, val: 400) # Update how many documents store in the cache\ncache.clear          # Clear cache\ncache.to_h           # Hash of the cache\n```\n\nNB: If you insert a max value higher than the quantity of elements in the Cache, then the first elements in excess will be removed from the Cache.\n\nIf the limit of the Cache for one type is reached, then the first element cached of that type will be deleted from the Cache.\n\n\n\u003ca name=\"ArangoError\"\u003e\u003c/a\u003e\n## Arango::Error\n\nError from ArangoRB are managed by Arango::Error.\nEach ArangoRB error is provided of a code and a message. The list of code can be find in the file lib/Error.rb\n\n``` ruby\nbegin\n  Arango::Collection.new name: \"Test\", database: not_a_database\nrescue Arango::Error =\u003e e\n  e.message # Message of the error\n  e.code    # ArangoRB code, each ArangoRB errors provides a list of errors\n  e.data    # More information about the error\n  e.to_h    # Hash version of the error\nend\n```\n\nArango::Error has a children class called Arango::ErrorDB to handle Errors coming from wrong HTTP requests.\n\n``` ruby\nbegin\n  Arango::Collection.new(name: \"DuplicateCollection\", database: myDatabase).create\nrescue Arango::Error =\u003e e\n  e.message  # Message of the error\n  e.code     # HTTP error code\n  e.data     # More information about the error\n  e.errorNum # ArangoDB errorNum code\n  e.action   # Type of request done to ArangoDB (POST, GET, ...)\n  e.url      # URL requested to ArangoDB\n  e.request  # Request made to ArangoDB\n  e.to_h     # Hash version of the error\nend\n```\n\n\u003ca name=\"testing\"\u003e\u003c/a\u003e\n## Testing\n\nTo test ArangoRB you can use:\n\n``` ruby\nrspec spec/arangoRB_helper.rb\nruby examples/year.rb\nruby examples/year2.rb\n```\n\nRemember however the following:\n* Setup the correct server in lib/spec_helper.rb and in the examples\n* The test examples/year2.rb should run much after the test examples/year.rb, since the last test is dependent from the conclusion of the first test (that is running in async).\n\n\u003ca name=\"differences\"\u003e\u003c/a\u003e\n## Differences between version 1.4 and 2.0\n\nArangoRB 1.4 and ArangoRB 2.0 are not compatible.\nThe new version provide different improvements.\n* Now all the instances are in a module Arango. This means that previous classes like ArangoServer will become Arango::Server.\n* Arango::Server is now an instance. This means that ArangoRB 2.0 will permits to use different servers.\n* ArangoRB has implemented connection_pool.\n* ArangoRB has now a better implementation of Cache.\n* The returned values are returned with symbols as keys.\n* Oj is used for parsing instead of JSON.\n* Add supports for View and Foxx. The least is untested.\n* Better hierarchy handling between the different instances. For example now myDocument.database will return the database instance that includes the document.\n* Better handling of replication (untested).\n* Clean in general the code (for future maintainer).\n* Now errors are handled by Arango::Error.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStefanoMartin%2FArangoRB","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FStefanoMartin%2FArangoRB","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FStefanoMartin%2FArangoRB/lists"}