A mongo DB client for Prolog

This package implements a mongo client using libmongoc-1.0.0, and declares a couple of Prolog predicates to interact with mongo DB from Prolog code. This includes predicates used to store, update or retrieve documents, as well as exporting, importing collections, and setting up their search indices.

One usecase is logging of ROS messages, in which case each DB collection corresponds to a ROS topic and is named accordingly. The records in collections are messages published on the topic and their structure is given by ROS message definitions. Using mongodb-log ROS messages can be recorded in advance or while KnowRob is running. ROS messages are usually stamped, and thus a timestamp value ends up in the DB records that should be used for indexing such that KnowRob can quickly find records given some time instant.

As an example, consider the following DB layout which is based on the PoseStamped message send via the communication topic tf:

{"tf": {
    "header": {
        "seq":      "integer",
        "stamp":    "time",
        "frame_id": "string"
    },
    "pose": {
        "position":    { "x": "double", "y": "double", "z": "double" },
        "orientation": { "x": "double", "y": "double", "z": "double", "w": "double" }
    }
}}

In the layout, the name tf corresponds to a named collection in the DB that collects recorded PoseStamped messages send via the named topic tf. The collection should be indexed by the key header.stamp such that the mongo server can quickly filter out records based on the timestamp when they were acquired. Note in case of array values (as for tf) it is important that the indexed key has identical values for all array members (e.g., the same header stamp in case of tf) -- however, it is advised to avoid generating indices over arrays. For tf, this means that it might be best to store each tranform in an individual document.

Querying mongo

Documents in mongo DB can be retrieved by first creating a cursor on a named collection, and then reading individual documents until the cursor has reached the last document matching the query. Cursors can limit the results, sort them, and filter them according to a pattern given in the query. The query is generally given as Prolog list holding two elements: the key (or operator) and the value. However, to avoid conversion problems, the value must be wrapped in an atom indicating its type.

As an example, below is a query that retrieves documents from a collection named triples. The cursor only retrieves documents where the subject key has the value "Obj1", and where the begin field has a date value smaller then the Unix timestamp 1579888948.52.

mng_cursor_create(roslog,triples,Cursor),
mng_cursor_filter(Cursor,['subject',['$eq',string('Obj1')]]),
mng_cursor_filter(Cursor,['begin',['$lte',time(1579888948.52)]]),
mng_cursor_next(Cursor,Doc),
mng_cursor_destroy(Cursor).

Note Make sure to destroy a cursor once you are done with it. Usually you would want to wrap the cursor operation into a call of setup_call_cleanup/3.

More complex filters may use, e.g., disjunction as in:

mng_cursor_filter(Cursor,['$or',
    array([['end',    ['$gte',time(Stamp)]],
           ['end',    ['$exists',bool(0)]]])]).

These expressions are generically mapped to BSON terms. Hence, any command supported by your mongo server can be written in such an expression.

Prolog files

__init__.pl
client.pl  -- A mongo DB client for Prolog.
mng_bulk_write/3Performs bulk operations.
mng_collection/2True if Collection is an existing collection in the named database.
mng_cursor_ascending/2Configure a cursor to yield documents in ascending order.
mng_cursor_create/3Creates a new query cursor.
mng_cursor_descending/2Configure a cursor to yield documents in descending order.
mng_cursor_destroy/1Destroys a query cursor.
mng_cursor_filter/2Appends an additional condition for documents matching the cursor.
mng_cursor_limit/2Limit the maximum number of documents a cursor may yield.
mng_cursor_materialize/2Yields results of the given database cursor, if any.
mng_cursor_next/2Yields the next matching document of the given database cursor, if any.
mng_db_name/1Get the name of the database the client is connected to.
mng_distinct_values/4Find all distinct values associated to Key in the given named database collection.
mng_drop/2Drop a named collection.
mng_dump/2Dump a named database by calling the mongodump commandline tool.
mng_dump_collection/3Dump a named database collection by calling the mongodump commandline tool.
mng_find/4Create a database cursor with given filter query and yield its results.
mng_get_db/3Get database and collection name for type of data denoted by DBType identifier.
mng_get_dict/3Get a key-value pair from a dictionary.
mng_index_create/2Creates compound search indices.
mng_index_create/3Creates a compound search index.
mng_one_db/2Get a special database collection with just one empty document.
mng_operator/2A mapping between Prolog operators and mongo DB operators.
mng_query_value/2Creates a query document from a query term.
mng_regex_prefix/2Create a regex pattern for matching entries with some prefix.
mng_remove/3Removes all documents matching Query from a named collection.
mng_restore/2Restore named database by calling the mongorestore commandline tool.
mng_store/3Stores a document in a named database collection.
mng_strip/4Strips a value term from its operator and type.
mng_strip_operator/3Strip the operator of a value term.
mng_strip_type/3Strip the type of a value term.
mng_strip_variable/2Strips variable from a value term.
mng_typed_value/2Ensure that Term includes a unary type term.
mng_unflatten/2Translates a flattened document into a nested one.
mng_unwatch/1Stop an existing change stream associated to the given identifier.
mng_update/4Updates all documents in a named collection that match Query.
mng_uri/1Get the URI connection string.
mng_watch/5Start a new change stream operation on given collection and filter documents with given aggregation pipeline.