الانتقال إلى المحتوى الرئيسي

نظرة عامة

يتيح لك قاموس regexp_tree ربط المفاتيح بالقيم استنادًا إلى أنماط تعابير نمطية هرمية. وهو مُحسَّن لعمليات lookup المعتمدة على مطابقة الأنماط (مثل تصنيف السلاسل النصية، كسلاسل user agent، عبر مطابقة أنماط regex) بدلًا من المطابقة الدقيقة للمفاتيح.

استخدام قاموس شجرة التعبيرات النمطية مع مصدر YAMLRegExpTree

تُعرَّف قواميس شجرة التعبيرات النمطية في ClickHouse مفتوح المصدر باستخدام المصدر YAMLRegExpTree، مع تزويده بمسار إلى ملف YAML يحتوي على شجرة التعبيرات النمطية.
Query
CREATE DICTIONARY regexp_dict
(
    regexp String,
    name String,
    version String
)
PRIMARY KEY(regexp)
SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml'))
LAYOUT(regexp_tree)
...
يمثّل مصدر القاموس YAMLRegExpTree بنية شجرة التعبيرات النمطية. على سبيل المثال:
- regexp: 'Linux/(\d+[\.\d]*).+tlinux'
  name: 'TencentOS'
  version: '\1'

- regexp: '\d+/tclwebkit(?:\d+[\.\d]*)'
  name: 'Android'
  versions:
    - regexp: '33/tclwebkit'
      version: '13'
    - regexp: '3[12]/tclwebkit'
      version: '12'
    - regexp: '30/tclwebkit'
      version: '11'
    - regexp: '29/tclwebkit'
      version: '10'
يتكوّن هذا التكوين من قائمة بعُقَد شجرة التعبيرات النمطية. ولكل عقدة البنية التالية:
  • regexp: التعبير النمطي للعقدة.
  • attributes: قائمة بسمات القاموس المعرّفة من قِبل المستخدم. في هذا المثال، توجد سمتان: name وversion. تحدّد العقدة الأولى كلتا السمتين. أما العقدة الثانية فتحدّد السمة name فقط. وتوفّر العُقَد الفرعية للعقدة الثانية السمة version.
    • قد تحتوي قيمة السمة على مراجع خلفية تشير إلى مجموعات الالتقاط في التعبير النمطي المطابِق. في المثال، تتكوّن قيمة السمة version في العقدة الأولى من مرجع خلفي \1 إلى مجموعة الالتقاط (\d+[\.\d]*) في التعبير النمطي. وتتراوح أرقام المراجع الخلفية من 1 إلى 9، وتُكتب بالشكل $1 أو \1 (للرقم 1). ويُستبدل المرجع الخلفي بمجموعة الالتقاط المطابِقة أثناء تنفيذ الاستعلام.
  • child nodes: قائمة بالعُقَد الفرعية لعقدة في شجرة التعبيرات النمطية، ولكل منها سماتها الخاصة وعُقَد فرعية خاصة بها (عند وجودها). وتتم مطابقة السلاسل النصية بأسلوب التعمّق أولًا. وإذا طابقت سلسلة نصية عقدة regexp، يتحقق القاموس مما إذا كانت تطابق أيضًا العُقَد الفرعية لتلك العقدة. وإذا كان الأمر كذلك، تُسنَد سمات أعمق عقدة مطابِقة. وتستبدل سمات العقدة الفرعية السمات المناظرة لها في العقد الأصلية. ويمكن أن يكون اسم العُقَد الفرعية في ملفات YAML أي اسم، مثل versions في المثال أعلاه.
لا تسمح قواميس شجرة التعبيرات النمطية بالوصول إلا باستخدام الدوال dictGet وdictGetOrDefault وdictGetAll. على سبيل المثال:
Query
SELECT dictGet('regexp_dict', ('name', 'version'), '31/tclwebkit1024');
Response
┌─dictGet('regexp_dict', ('name', 'version'), '31/tclwebkit1024')─┐
│ ('Android','12')                                                │
└─────────────────────────────────────────────────────────────────┘
في هذه الحالة، نطابق أولاً التعبير النمطي \d+/tclwebkit(?:\d+[\.\d]*) في العقدة الثانية من الطبقة العليا. ثم يواصل القاموس البحث في العقد الفرعية ويجد أن السلسلة تطابق أيضاً 3[12]/tclwebkit. ونتيجةً لذلك، تكون قيمة السمة name هي Android (محددة في الطبقة الأولى)، وتكون قيمة السمة version هي 12 (محددة في العقدة الفرعية). باستخدام ملف تهيئة YAML متقدم، يمكنك استخدام قواميس شجرة التعبيرات النمطية كمحلّل لسلسلة user agent. يدعم ClickHouse uap-core، ويمكنك الاطلاع على كيفية استخدامه في الاختبار functional 02504_regexp_dictionary_ua_parser

جمع قيم السمات

أحيانًا يكون من المفيد إرجاع القيم من عدة تعبيرات نمطية جرت مطابقتها، بدلًا من إرجاع قيمة عقدة طرفية فقط. في هذه الحالات، يمكن استخدام الدالة المتخصصة dictGetAll. إذا كانت للعقدة قيمة سمة من النوع T، فستُرجِع dictGetAll مصفوفة من النوع Array(T) تحتوي على صفر أو أكثر من القيم. افتراضيًا، لا يكون عدد المطابقات المُعادة لكل مفتاح مقيّدًا. ويمكن تمرير حد اختياري باعتباره الوسيط الرابع إلى dictGetAll. وتُملأ المصفوفة بترتيب طوبولوجي، ما يعني أن العقد الفرعية تأتي قبل العقد الأصلية، وأن العقد الشقيقة تتبع الترتيب الوارد في المصدر. مثال:
CREATE DICTIONARY regexp_dict
(
    regexp String,
    tag String,
    topological_index Int64,
    captured Nullable(String),
    parent String
)
PRIMARY KEY(regexp)
SOURCE(YAMLRegExpTree(PATH '/var/lib/clickhouse/user_files/regexp_tree.yaml'))
LAYOUT(regexp_tree)
LIFETIME(0)
# /var/lib/clickhouse/user_files/regexp_tree.yaml
- regexp: 'clickhouse\.com'
  tag: 'ClickHouse'
  topological_index: 1
  paths:
    - regexp: 'clickhouse\.com/docs(.*)'
      tag: 'ClickHouse Documentation'
      topological_index: 0
      captured: '\1'
      parent: 'ClickHouse'

- regexp: '/docs(/|$)'
  tag: 'Documentation'
  topological_index: 2

- regexp: 'github.com'
  tag: 'GitHub'
  topological_index: 3
  captured: 'NULL'
Query
CREATE TABLE urls (url String) ENGINE=MergeTree ORDER BY url;
INSERT INTO urls VALUES ('clickhouse.com'), ('clickhouse.com/docs/en'), ('github.com/clickhouse/tree/master/docs');
SELECT url, dictGetAll('regexp_dict', ('tag', 'topological_index', 'captured', 'parent'), url, 2) FROM urls;
Response
┌─url────────────────────────────────────┬─dictGetAll('regexp_dict', ('tag', 'topological_index', 'captured', 'parent'), url, 2)─┐
│ clickhouse.com                         │ (['ClickHouse'],[1],[],[])                                                            │
│ clickhouse.com/docs/en                 │ (['ClickHouse Documentation','ClickHouse'],[0,1],['/en'],['ClickHouse'])              │
│ github.com/clickhouse/tree/master/docs │ (['Documentation','GitHub'],[2,3],[NULL],[])                                          │
└────────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────┘

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

يمكن تعديل سلوك مطابقة الأنماط باستخدام بعض إعدادات القاموس:
  • regexp_dict_flag_case_insensitive: استخدام المطابقة غير الحساسة لحالة الأحرف (القيمة الافتراضية هي false). يمكن تجاوز هذا الإعداد في تعابير فردية باستخدام (?i) و (?-i).
  • regexp_dict_flag_dotall: السماح للرمز . بمطابقة أحرف السطر الجديد (القيمة الافتراضية هي false).

استخدام قاموس شجرة التعبيرات النمطية في ClickHouse Cloud

يعمل المصدر YAMLRegExpTree في ClickHouse مفتوح المصدر، لكنه لا يعمل في ClickHouse Cloud. لاستخدام قواميس شجرة التعبيرات النمطية في ClickHouse Cloud، أنشئ أولًا محليًا في ClickHouse مفتوح المصدر قاموس شجرة تعبيرات نمطية من ملف YAML، ثم صدّر هذا القاموس إلى ملف CSV باستخدام دالة الجدول dictionary وبند INTO OUTFILE.
SELECT * FROM dictionary(regexp_dict) INTO OUTFILE('regexp_dict.csv')
محتوى ملف CSV:
1,0,"Linux/(\d+[\.\d]*).+tlinux","['version','name']","['\\1','TencentOS']"
2,0,"(\d+)/tclwebkit(\d+[\.\d]*)","['comment','version','name']","['test $1 and $2','$1','Android']"
3,2,"33/tclwebkit","['version']","['13']"
4,2,"3[12]/tclwebkit","['version']","['12']"
5,2,"3[12]/tclwebkit","['version']","['11']"
6,2,"3[12]/tclwebkit","['version']","['10']"
مخطط الملف المُفرَّغ هو:
  • id UInt64: معرّف عقدة RegexpTree.
  • parent_id UInt64: معرّف العقدة الأب لإحدى العقد.
  • regexp String: سلسلة التعبير النمطي.
  • keys Array(String): أسماء السمات التي يحدّدها المستخدم.
  • values Array(String): قيم السمات التي يحدّدها المستخدم.
لإنشاء القاموس في ClickHouse Cloud، أنشئ أولاً جدولًا باسم regexp_dictionary_source_table ببنية الجدول التالية:
CREATE TABLE regexp_dictionary_source_table
(
    id UInt64,
    parent_id UInt64,
    regexp String,
    keys   Array(String),
    values Array(String)
) ENGINE=Memory;
ثم حدِّث ملف CSV المحلي باستخدام
clickhouse client \
    --host MY_HOST \
    --secure \
    --password MY_PASSWORD \
    --query "
    INSERT INTO regexp_dictionary_source_table
    SELECT * FROM input ('id UInt64, parent_id UInt64, regexp String, keys Array(String), values Array(String)')
    FORMAT CSV" < regexp_dict.csv
يمكنك الاطلاع على كيفية إدراج الملفات المحلية لمزيد من التفاصيل. بعد تهيئة جدول المصدر، يمكننا إنشاء RegexpTree باستخدام جدول المصدر:
CREATE DICTIONARY regexp_dict
(
    regexp String,
    name String,
    version String
PRIMARY KEY(regexp)
SOURCE(CLICKHOUSE(TABLE 'regexp_dictionary_source_table'))
LIFETIME(0)
LAYOUT(regexp_tree);
آخر تعديل في ٢٩ يونيو ٢٠٢٦