الانتقال إلى المحتوى الرئيسي
يمكن لـ ClickHouse تحديد بنية بيانات JSON تلقائيًا. ويمكن استخدام ذلك للاستعلام عن بيانات JSON مباشرةً، على سبيل المثال من القرص باستخدام clickhouse-local أو من حاويات S3، و/أو إنشاء مخططات تلقائيًا قبل تحميل البيانات إلى ClickHouse.

متى تستخدم استنتاج الأنواع

  • بنية متسقة - يجب أن تحتوي البيانات التي ستستنتج منها الأنواع على جميع المفاتيح التي تهمك. يستند استنتاج الأنواع إلى أخذ عينات من البيانات حتى الحد الأقصى لعدد الصفوف أو البايتات. وأي بيانات تأتي بعد العينة وتحتوي على أعمدة إضافية سيتم تجاهلها، ولن يمكن الاستعلام عنها.
  • أنواع متسقة - يجب أن تكون أنواع البيانات للمفاتيح المحددة متوافقة، أي يجب أن يكون من الممكن تحويل أحد الأنواع إلى الآخر تلقائيًا.
إذا كانت بيانات JSON لديك أكثر ديناميكية، بحيث تُضاف إليها مفاتيح جديدة وتكون فيه أنواع متعددة ممكنة للمسار ذاته، فراجع “العمل مع البيانات شبه المنظمة والديناميكية”.

اكتشاف الأنواع

يفترض ما يلي أن بنية JSON متسقة وأن لكل مسار نوعًا واحدًا فقط. استخدمت أمثلتنا السابقة نسخة مبسطة من مجموعة بيانات Python PyPI بتنسيق NDJSON. في هذا القسم، نستعرض مجموعة بيانات أكثر تعقيدًا ذات بُنى متداخلة، وهي مجموعة بيانات arXiv التي تضم 2.5 مليون ورقة علمية. ويمثل كل صف في مجموعة البيانات هذه، الموزعة بتنسيق NDJSON، ورقة أكاديمية منشورة. ويظهر أدناه صف على سبيل المثال:
تتطلب هذه البيانات مخططًا أكثر تعقيدًا بكثير من الأمثلة السابقة. نوضح أدناه عملية تعريف هذا المخطط، مع تقديم أنواع معقدة مثل Tuple وArray. تُخزَّن مجموعة البيانات هذه في حاوية S3 عامة على s3://datasets-documentation/arxiv/arxiv.json.gz. يمكنك ملاحظة أن مجموعة البيانات أعلاه تحتوي على كائنات JSON متداخلة. وبينما ينبغي لك إعداد مخططاتك وإدارة إصداراتها، يتيح الاستدلال استنتاج الأنواع من البيانات. وهذا يسمح بإنشاء DDL الخاص بالمخطط تلقائيًا، مما يجنّب الحاجة إلى إنشائه يدويًا ويُسرّع عملية التطوير.
الاكتشاف التلقائي للتنسيقبالإضافة إلى اكتشاف المخطط، سيستدل استنتاج مخطط JSON تلقائيًا على تنسيق البيانات من امتداد الملف ومحتوياته. ونتيجةً لذلك، يُكتشف الملف أعلاه تلقائيًا على أنه NDJSON.
يُظهر استخدام دالة s3 مع الأمر DESCRIBE الأنواع التي سيجري استنتاجها.
تجنّب القيم NULLيمكنك ملاحظة أن الكثير من الأعمدة جرى اكتشافها على أنها من النوع Nullable. نحن لا نوصي باستخدام النوع Nullable إلا عند الضرورة القصوى. يمكنك استخدام schema_inference_make_columns_nullable للتحكم في الحالات التي يُطبَّق فيها Nullable.
يمكننا ملاحظة أن معظم الأعمدة قد اكتُشفت تلقائيًا على أنها String، بينما اكتُشف العمود update_date بشكل صحيح على أنه Date. وقد أُنشئ العمود versions بصيغة Array(Tuple(created String, version String)) لتخزين قائمة من الكائنات، في حين عُرِّف authors_parsed على أنه Array(Array(String)) للمصفوفات المتداخلة.
التحكم في اكتشاف الأنواعيمكن التحكم في الاكتشاف التلقائي للتواريخ وأنواع DateTime من خلال الإعدادين input_format_try_infer_dates وinput_format_try_infer_datetimes على التوالي (وكلاهما مُمكَّن افتراضيًا). كما يتحكم الإعداد input_format_json_try_infer_named_tuples_from_objects في استنتاج الكائنات على أنها Tuples. ويمكن العثور هنا على إعدادات أخرى تتحكم في استنتاج المخطط في JSON، مثل الاكتشاف التلقائي للأرقام.

الاستعلام عن JSON

يفترض ما يلي أن بنية JSON متسقة وأن لكل مسار نوعًا واحدًا فقط. يمكننا الاعتماد على استنتاج المخطط للاستعلام عن بيانات JSON مباشرةً. في ما يلي، نحدّد أبرز المؤلفين لكل سنة، مع الاستفادة من اكتشاف التواريخ والمصفوفات تلقائيًا.
يتيح لنا استنتاج المخطط الاستعلام عن ملفات JSON من دون الحاجة إلى تحديد المخطط، مما يسرّع مهام تحليل البيانات عند الحاجة.

إنشاء الجداول

يمكننا الاعتماد على استنتاج المخطط لإنشاء مخطط جدول. يؤدي الأمر CREATE AS EMPTY التالي إلى استنتاج تعريف DDL للجدول ثم إنشاء الجدول. لا يؤدي هذا إلى تحميل أي بيانات:
للتحقق من مخطط الجدول، نستخدم الأمر SHOW CREATE TABLE:
ما سبق هو المخطط الصحيح لهذه البيانات. يعتمد استنتاج المخطط على أخذ عينات من البيانات وقراءة البيانات صفًا صفًا. تُستخرج قيم الأعمدة وفقًا للتنسيق، مع استخدام محللات متداخلة وأساليب استدلالية لتحديد النوع لكل قيمة. يتحكم الإعدادان input_format_max_rows_to_read_for_schema_inference (25000 افتراضيًا) وinput_format_max_bytes_to_read_for_schema_inference (32MB افتراضيًا) في الحد الأقصى لعدد الصفوف والبايتات المقروءة من البيانات أثناء استنتاج المخطط. إذا لم يكن الاكتشاف دقيقًا، يمكنك تقديم تلميحات كما هو موضح هنا.

إنشاء الجداول من المقتطفات

يستخدم المثال أعلاه ملفًا على S3 لإنشاء مخطط الجدول. وقد ترغب في إنشاء مخطط انطلاقًا من مقتطف يتكوّن من row واحدة. ويمكن تحقيق ذلك باستخدام الدالة format كما هو موضح أدناه:

تحميل بيانات JSON

يفترض ما يلي أن بيانات JSON ذات بنية متسقة، وأن لكل مسار نوعًا واحدًا فقط. أنشأت الأوامر السابقة جدولًا يمكن تحميل البيانات إليه. يمكنك الآن insert البيانات إلى جدولك باستخدام INSERT INTO SELECT التالي:
للاطلاع على أمثلة على تحميل البيانات من مصادر أخرى، مثل ملف، راجع هنا. بمجرد تحميلها، يمكننا الاستعلام عن بياناتنا، مع استخدام التنسيق PrettyJSONEachRow اختياريًا لعرض الصفوف ببنيتها الأصلية:

التعامل مع الأخطاء

أحيانًا قد تكون لديك بيانات غير صالحة. على سبيل المثال، قد تحتوي أعمدة معيّنة على نوع غير صحيح أو كائن JSON غير منسّق بشكل صحيح. لهذا، يمكنك استخدام الإعدادين input_format_allow_errors_num وinput_format_allow_errors_ratio للسماح بتجاهل عدد معيّن من الصفوف إذا كانت البيانات تتسبب في أخطاء عند الإدراج. بالإضافة إلى ذلك، يمكن تقديم تلميحات للمساعدة في الاستدلال.

العمل مع البيانات شبه المنظَّمة والديناميكية

استخدم مثالنا السابق JSON ثابتًا بأسماء مفاتيح وأنواع معروفة مسبقًا. لكن الحال لا يكون كذلك غالبًا، إذ قد تُضاف مفاتيح جديدة أو تتغير أنواعها. وهذا شائع في حالات استخدام مثل بيانات Observability. يتعامل ClickHouse مع ذلك من خلال النوع المخصص JSON. إذا كنت تعلم أن بيانات JSON لديك شديدة الديناميكية وتحتوي على عدد كبير من المفاتيح الفريدة وأنواع متعددة للمفاتيح نفسها، فنوصي بعدم استخدام استنتاج المخطط مع JSONEachRow لمحاولة استنتاج عمود لكل مفتاح، حتى لو كانت البيانات بتنسيق newline-delimited JSON. تأمل المثال التالي من إصدار موسَّع من مجموعة بيانات Python PyPI dataset المذكورة أعلاه. هنا أضفنا عمود tags عشوائيًا يضم أزواجًا عشوائية من المفاتيح والقيم.
تتوفّر عيّنة من هذه البيانات للعامة بتنسيق JSON مفصول بأسطر جديدة. إذا حاولنا استنتاج المخطط لهذا الملف، فستجد أن الأداء ضعيف وأن الاستجابة مطوّلة للغاية:
المشكلة الأساسية هنا هي أن تنسيق JSONEachRow يُستخدم للاستنتاج. إذ يحاول استنتاج نوع عمود لكل مفتاح في JSON — أي إنه يحاول فعليًا فرض مخطط ثابت على البيانات من دون استخدام النوع JSON. عند وجود آلاف الأعمدة الفريدة، يصبح هذا النهج في الاستنتاج بطيئًا. وكبديل، يمكنك استخدام تنسيق JSONAsObject. يتعامل JSONAsObject مع الإدخال بالكامل على أنه كائن JSON واحد، ويخزّنه في عمود واحد من النوع JSON، مما يجعله أنسب لحمولات JSON شديدة الديناميكية أو المتداخلة.
يُعد هذا التنسيق ضروريًا أيضًا عندما تكون للأعمدة أنواع متعددة يتعذر التوفيق بينها. على سبيل المثال، افترض وجود ملف sample.json يحتوي على JSON مفصول بأسطر جديدة كما يلي:
في هذه الحالة، يستطيع ClickHouse التوفيق بين تعارض الأنواع وتحديد العمود a على أنه Nullable(String).
التحويل القسري للنوعيمكن التحكم في هذا التحويل القسري للنوع عبر عدد من الإعدادات. يعتمد المثال أعلاه على الإعداد input_format_json_read_numbers_as_strings.
ومع ذلك، فإن بعض الأنواع غير متوافقة. انظر إلى المثال التالي:
في هذه الحالة، لا يمكن إجراء أي نوع من تحويل الأنواع هنا. ولذلك يفشل الأمر DESCRIBE:
في هذه الحالة، يتعامل JSONAsObject مع كل صف باعتباره قيمة واحدة من النوع JSON (ما يتيح أن يكون للعمود نفسه أكثر من نوع). وهذا أمر أساسي:

للمزيد من القراءة

للتعرّف بمزيد من التفصيل على استدلال أنواع البيانات، يمكنك الرجوع إلى صفحة التوثيق هذه.
آخر تعديل في ٢٩ يونيو ٢٠٢٦