Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Moteur de table MongoDB

Le moteur de table MongoDB est un moteur de table en lecture seule qui permet de lire des données à partir d’une collection distante dans MongoDB.

Seul MongoDB >=7 est pris en charge. La Seed list(mongodb+srv) n’est pas encore prise en charge.

Création d’une table

CREATE TABLE [IF NOT EXISTS] [db.]table_name
(
    name1 [type1],
    name2 [type2],
    ...
) ENGINE = MongoDB(host:port, database, collection, user, password[, options[, oid_columns]]);

Paramètres du moteur

Paramètre Description
host:port Adresse du serveur MongoDB.
database Nom de la base de données distante.
collection Nom de la collection distante.
user Utilisateur MongoDB.
password Mot de passe de l'utilisateur.
options Facultatif. Options de la chaîne de connexion MongoDB, sous la forme d'une chaîne au format URL. Par ex. 'authSource=admin&ssl=true'
oid_columns Liste de colonnes séparées par des virgules devant être traitées comme oid dans la clause WHERE. _id par défaut.

Sinon, vous pouvez transmettre un URI :

ENGINE = MongoDB(uri, collection[, oid_columns]);

Paramètres du moteur

Paramètre Description
uri URI de connexion au serveur MongoDB.
collection Nom de la collection distante.
oid_columns Liste de colonnes séparées par des virgules à traiter comme oid dans la clause WHERE. _id par défaut.

Correspondance des types

MongoDB ClickHouse
bool, int32, int64 tout type numérique sauf Decimals, Boolean, String
double Float64, String
date Date, Date32, DateTime, DateTime64, String
string String, tout type numérique (sauf Decimals) s'il est correctement formaté
document String (au format JSON)
array Array, String (au format JSON)
oid String
binary String si dans une colonne, chaîne encodée en base64 si dans un tableau ou un document
uuid (binary subtype 4) UUID
tout autre String

Si la clé est introuvable dans le document MongoDB (par exemple, si le nom de la colonne ne correspond pas), la valeur par défaut ou NULL (si la colonne est de type Nullable) sera insérée.

OID

Si vous voulez qu’une String soit traitée comme un oid dans la clause WHERE, il suffit d’indiquer le nom de la colonne dans le dernier argument du moteur de table. Cela peut être nécessaire lors d’une requête sur un enregistrement via la colonne _id, qui a par défaut le type oid dans MongoDB. Si le champ _id de la table est d’un autre type, par exemple uuid, vous devez spécifier un oid_columns vide ; sinon, la valeur par défaut de ce paramètre, _id, sera utilisée.

db.sample_oid.insertMany([
    {"another_oid_column": ObjectId()},
]);

db.sample_oid.find();
[
    {
        "_id": {"$oid": "67bf6cc44ebc466d33d42fb2"},
        "another_oid_column": {"$oid": "67bf6cc40000000000ea41b1"}
    }
]

Par défaut, seul _id est considéré comme une colonne oid.

CREATE TABLE sample_oid
(
    _id String,
    another_oid_column String
) ENGINE = MongoDB('mongodb://user:pass@host/db', 'sample_oid');

SELECT count() FROM sample_oid WHERE _id = '67bf6cc44ebc466d33d42fb2'; --will output 1.
SELECT count() FROM sample_oid WHERE another_oid_column = '67bf6cc40000000000ea41b1'; --will output 0

Dans ce cas, le résultat sera 0, car ClickHouse ne sait pas que another_oid_column est de type oid, alors corrigeons cela :

CREATE TABLE sample_oid
(
    _id String,
    another_oid_column String
) ENGINE = MongoDB('mongodb://user:pass@host/db', 'sample_oid', '_id,another_oid_column');

-- or

CREATE TABLE sample_oid
(
    _id String,
    another_oid_column String
) ENGINE = MongoDB('host', 'db', 'sample_oid', 'user', 'pass', '', '_id,another_oid_column');

SELECT count() FROM sample_oid WHERE another_oid_column = '67bf6cc40000000000ea41b1'; -- will output 1 now

Clauses prises en charge

Seules les requêtes contenant des expressions simples sont prises en charge (par exemple, WHERE field = <constant> ORDER BY field2 LIMIT <constant>). Ces expressions sont traduites dans le langage de requête de MongoDB et exécutées côté serveur. Vous pouvez désactiver toutes ces restrictions avec mongodb_throw_on_unsupported_query. Dans ce cas, ClickHouse essaie de convertir la requête dans la mesure du possible, mais cela peut entraîner un scan complet de la table et un traitement côté ClickHouse.

Exemple d'utilisation

En supposant que le jeu de données sample_mflix soit chargé dans MongoDB

Créez une table dans ClickHouse permettant de lire des données à partir d'une collection MongoDB :

Querysql
CREATE TABLE sample_mflix_table
(
    _id String,
    title String,
    plot String,
    genres Array(String),
    directors Array(String),
    writers Array(String),
    released Date,
    imdb String,
    year String
) ENGINE = MongoDB('mongodb://<USERNAME>:<PASSWORD>@atlas-sql-6634be87cefd3876070caf96-98lxs.a.query.mongodb.net/sample_mflix?ssl=true&authSource=admin', 'movies');
Querysql
SELECT count() FROM sample_mflix_table
Responsetext
┌─count()─┐
│   21349 │
└─────────┘
Querysql
-- JSONExtractString cannot be pushed down to MongoDB
SET mongodb_throw_on_unsupported_query = 0;

-- Find all 'Back to the Future' sequels with rating > 7.5
SELECT title, plot, genres, directors, released FROM sample_mflix_table
WHERE title IN ('Back to the Future', 'Back to the Future Part II', 'Back to the Future Part III')
    AND toFloat32(JSONExtractString(imdb, 'rating')) > 7.5
ORDER BY year
FORMAT Vertical;
Responsetext
Row 1:
──────
title:     Back to the Future
plot:      A young man is accidentally sent 30 years into the past in a time-traveling DeLorean invented by his friend, Dr. Emmett Brown, and must make sure his high-school-age parents unite in order to save his own existence.
genres:    ['Adventure','Comedy','Sci-Fi']
directors: ['Robert Zemeckis']
released:  1985-07-03

Row 2:
──────
title:     Back to the Future Part II
plot:      After visiting 2015, Marty McFly must repeat his visit to 1955 to prevent disastrous changes to 1985... without interfering with his first trip.
genres:    ['Action','Adventure','Comedy']
directors: ['Robert Zemeckis']
released:  1989-11-22
Querysql
-- Find top 3 movies based on Cormac McCarthy's books
SELECT title, toFloat32(JSONExtractString(imdb, 'rating')) AS rating
FROM sample_mflix_table
WHERE arrayExists(x -> x LIKE 'Cormac McCarthy%', writers)
ORDER BY rating DESC
LIMIT 3;
Responsetext
┌─title──────────────────┬─rating─┐
│ No Country for Old Men │    8.1 │
│ The Sunset Limited     │    7.4 │
│ The Road               │    7.3 │
└────────────────────────┴────────┘

Dépannage

Vous pouvez voir la requête MongoDB générée dans les logs de niveau DEBUG.

Les détails de l’implémentation sont disponibles dans la documentation de mongocxx et de mongoc.

Navigation