الانتقال إلى المحتوى الرئيسي
محرك MongoDB هو محرك جدول للقراءة فقط يتيح قراءة البيانات من مجموعة بعيدة في MongoDB. لا تُدعَم إلا خوادم MongoDB بالإصدار v3.6+. كما أن Seed list(mongodb+srv) غير مدعومة بعد.

إنشاء جدول

CREATE TABLE [IF NOT EXISTS] [db.]table_name
(
    name1 [type1],
    name2 [type2],
    ...
) ENGINE = MongoDB(host:port, database, collection, user, password[, options[, oid_columns]]);
معلمات المحرك
ParameterDescription
host:portعنوان خادم MongoDB.
databaseاسم قاعدة البيانات البعيدة.
collectionاسم المجموعة البعيدة.
userمستخدم MongoDB.
passwordكلمة مرور المستخدم.
optionsاختياري. خيارات سلسلة الاتصال في MongoDB، على شكل سلسلة منسقة بصيغة URL. مثال: 'authSource=admin&ssl=true'
oid_columnsقائمة مفصولة بفواصل للأعمدة التي يجب التعامل معها باعتبارها oid في عبارة WHERE. القيمة الافتراضية هي _id.
إذا كنت تستخدم خدمة MongoDB Atlas السحابية، فيمكن الحصول على عنوان URL للاتصال من خيار ‘Atlas SQL’. Seed list(mongodb**+srv**) غير مدعومة بعد، ولكن ستُضاف في الإصدارات المستقبلية.
بدلاً من ذلك، يمكنك تمرير URI:
ENGINE = MongoDB(uri, collection[, oid_columns]);
معلمات المحرّك
المعلمةالوصف
uriمعرّف URI لاتصال خادم MongoDB.
collectionاسم المجموعة البعيدة.
oid_columnsقائمة مفصولة بفواصل للأعمدة التي يجب التعامل معها باعتبارها oid في عبارة WHERE. وتكون _id افتراضيًا.

مطابقة الأنواع

MongoDBClickHouse
bool, int32, int64أي نوع رقمي باستثناء Decimals، Boolean، String
doubleFloat64، String
dateDate، Date32، DateTime، DateTime64، String
stringString، أي نوع رقمي (باستثناء Decimals) إذا كان منسقًا بشكل صحيح
documentString (بصيغة JSON)
arrayArray، String (بصيغة JSON)
oidString
binaryString إذا كان في عمود، وسلسلة مرمّزة بترميز base64 إذا كانت داخل array أو document
uuid (binary subtype 4)UUID
any otherString
إذا لم يتم العثور على المفتاح في مستند MongoDB (على سبيل المثال، إذا كان اسم العمود غير مطابق)، فستُدرج القيمة الافتراضية أو NULL (إذا كان العمود من النوع Nullable).

OID

إذا كنت تريد التعامل مع String على أنه oid في عبارة WHERE، فما عليك سوى وضع اسم العمود في الوسيط الأخير من محرك الجدول. قد يكون ذلك ضروريًا عند الاستعلام عن سجل بواسطة العمود _id، إذ يكون نوعه افتراضيًا oid في MongoDB. إذا كان الحقل _id في الجدول من نوع آخر، مثل uuid، فستحتاج إلى تعيين oid_columns إلى قيمة فارغة، وإلا فستُستخدَم القيمة الافتراضية لهذه المعلمة، وهي _id.
db.sample_oid.insertMany([
    {"another_oid_column": ObjectId()},
]);

db.sample_oid.find();
[
    {
        "_id": {"$oid": "67bf6cc44ebc466d33d42fb2"},
        "another_oid_column": {"$oid": "67bf6cc40000000000ea41b1"}
    }
]
افتراضيًا، لا يُعامَل إلا _id باعتباره عمود 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
في هذه الحالة، ستكون النتيجة 0، لأن ClickHouse لا يعلم أن another_oid_column من النوع oid، لذا لنصحح ذلك:
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

العبارات المدعومة

لا تُدعَم إلا الاستعلامات التي تحتوي على expressions بسيطة (على سبيل المثال، WHERE field = <constant> ORDER BY field2 LIMIT <constant>). تُترجَم هذه expressions إلى query language الخاصة بـ MongoDB وتُنفَّذ على الخادم. يمكنك تعطيل جميع هذه القيود باستخدام mongodb_throw_on_unsupported_query. في هذه الحالة، يحاول ClickHouse تحويل query قدر الإمكان، لكن قد يؤدي ذلك إلى إجراء فحص كامل للـ table وتنفيذ processing على جانب ClickHouse.
من الأفضل دائمًا تحديد نوع القيمة الحرفية صراحةً لأن Mongo يتطلب filters صارمة من حيث النوع. على سبيل المثال، إذا كنت تريد التصفية حسب Date:
SELECT * FROM mongo_table WHERE date = '2024-01-01'
لن ينجح هذا لأن Mongo لن يحوّل السلسلة النصية إلى Date، لذا ستحتاج إلى تحويلها يدويًا:
SELECT * FROM mongo_table WHERE date = '2024-01-01'::Date OR date = toDate('2024-01-01')
ينطبق هذا على Date وDate32 وDateTime وBool وUUID.

مثال على الاستخدام

على افتراض أنّ مجموعة البيانات sample_mflix محمّلة في MongoDB أنشئ جدولًا في ClickHouse يتيح قراءة البيانات من مجموعة في MongoDB:
Query
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');
Query
SELECT count() FROM sample_mflix_table
Response
   ┌─count()─┐
1. │   21349 │
   └─────────┘
Query
-- 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;
Response
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
Query
-- 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;
Response
   ┌─title──────────────────┬─rating─┐
1. │ No Country for Old Men │    8.1 │
2. │ The Sunset Limited     │    7.4 │
3. │ The Road               │    7.3 │
   └────────────────────────┴────────┘

استكشاف الأخطاء وإصلاحها

يمكنك الاطلاع على استعلام MongoDB الذي تم إنشاؤه في السجلات على مستوى DEBUG. يمكن العثور على تفاصيل التنفيذ في وثائق mongocxx وmongoc.
آخر تعديل في ٢٩ يونيو ٢٠٢٦