في الأصل ، كان البحث عن القضايا محدودًا ببنية مسطحة بسيطة من الاستعلامات. ولكن مع بناء جملة البحث المتقدم، يمكنك الآن إنشاء عمليات البحث باستخدام العوامل المنطقية و/أو المشغلين والأقواس المتداخلة ، مما يفسد مجموعة المشكلات الدقيقة التي تهتم بها.
قدم بناء هذه الميزة تحديات كبيرة: ضمان التوافق المتخلف مع عمليات البحث الحالية ، والحفاظ على الأداء تحت حجم الاستعلام العالي ، وصياغة تجربة سهلة الاستخدام للبحث المتداخل. نحن متحمسون لنأخذك وراء الكواليس لمشاركة كيف أخذنا هذه الميزة التي تم طلبها منذ فترة طويلة من الفكرة إلى الإنتاج.
إليك ما يمكنك فعله مع بناء الجملة الجديد وكيف يعمل وراء الكواليس
يدعم البحث عن المشكلات الآن بناء الاستعلامات مع العوامل المنطقية و/أو المشغلين عبر الجميع الحقول ، مع القدرة على العش شروط الاستعلام. على سبيل المثال is:issue state:open author:rileybroughten (type:Bug OR type:Epic)
يجد كل شيء مشاكل هذا يفتح وكانت مؤلفإد Rileybroughten وهما من النوع حشرة أو ملحمي.

كيف وصلنا إلى هنا؟
في السابق ، كما ذكرنا ، دعم البحث عن القضايا فقط قائمة مسطحة من حقول الاستعلام والمصطلحات ، والتي انضمت ضمنيًا بواسطة منطقية و. على سبيل المثال ، الاستعلام assignee:@me label:support new-project
ترجم إلى “أعطني كل المشكلات التي يتم تعيينها لي ولديها الملصق يدعم و تحتوي على النص مشروع جديد.“
لكن مجتمع المطور كان طلب مزيد من المرونة في البحث عن القضيةو مرارا، لما يقرب من عقد من الزمان الآن. أرادوا أن يكونوا قادرين على العثور على جميع المشكلات التي كانت أيضاً الملصق support
أو الملصق question
باستخدام الاستعلام label:support OR label:question
. لذلك ، شحننا التعزيز تجاه هذا الطلب في عام 2021 ، عندما قمنا بتمكين البحث أو النمط باستخدام قائمة قيم مفصولة بفاصلة.
ومع ذلك ، ما زالوا يريدون المرونة في البحث بهذه الطريقة الجميع عدد الحقولوليس فقط تسميات مجال. لذلك وصلنا إلى العمل.
العمارة الفنية والتنفيذ

من منظور معماري ، قمنا بتبديل وحدة البحث الحالية للمشكلات (CompleSquery) ، مع وحدة بحث جديدة (MonditalissuesSequery) ، والتي كانت قادرة على التعامل مع الاستفسارات المتداخلة مع الاستمرار في دعم تنسيقات الاستعلام الحالية.
وشمل ذلك إعادة كتابة issueQuery ، وهي وحدة البحث التي قامت بتحليل سلاسل الاستعلام ورسمها في استفسارات Elasticsearch.

لإنشاء وحدة بحث جديدة ، احتجنا أولاً إلى فهم وحدة البحث الموجودة ، وكيف تدفق استعلام بحث واحد عبر النظام. على مستوى عال ، عندما يقوم المستخدم بإجراء بحث ، هناك ثلاث مراحل في تنفيذها:
- تحليل: تقسيم سلسلة إدخال المستخدم إلى بنية أسهل في معالجتها (مثل القائمة أو شجرة)
- استفسار: تحويل الهيكل المحسّن إلى وثيقة استعلام Elasticsearch ، وإجراء استعلام ضد Elasticsearch.
- تطبيع: تعيين النتائج التي تم الحصول عليها من Elasticsearch (JSON) إلى كائنات Ruby لسهولة الوصول وتشذيب النتائج لإزالة السجلات التي تمت إزالتها منذ ذلك الحين من قاعدة البيانات.
قدمت كل مرحلة تحدياتها الخاصة ، والتي سنستكشفها بمزيد من التفصيل أدناه. ال تطبيع ظلت الخطوة دون تغيير أثناء إعادة الكتابة ، لذلك لن نغوص في هذا الخط.
تحليل المرحلة
يتم تحليل سلسلة إدخال المستخدم (عبارة البحث) أولاً في بنية وسيطة. يمكن أن تشمل عبارة البحث:
- شروط الاستعلام: الكلمات ذات الصلة التي يحاول المستخدم العثور على مزيد من المعلومات حول (على سبيل المثال: “النماذج”)
- مرشحات البحث: هذه تقيد مجموعة مستندات البحث التي تم إرجاعها بناءً على بعض المعايير (على سبيل المثال: “المحالفين: ديبورا ديججز”)
مثال عبارة البحث:
- ابحث عن جميع المشكلات المعينة لي تحتوي على كلمة “مساحات الترميز”:
is:issue assignee:@me codespaces
- ابحث عن جميع المشكلات مع الملصق الوثائق التي تم تعيينها لي:
assignee:@me label:documentation
طريقة التحليل القديمة: قائمة مسطحة
عندما تم دعم الاستعلامات المسطحة والبسيطة فقط ، كان ذلك كافياً لتحليل سلسلة بحث المستخدم في قائمة مصطلحات البحث والمرشحات ، والتي سيتم تمريرها بعد ذلك إلى المرحلة التالية من عملية البحث.
طريقة التحليل الجديدة: شجرة بناء الجملة التجريدية
نظرًا لأن الاستعلامات المتداخلة قد تكون متكررة ، فإن تحليل سلسلة البحث في قائمة لم يعد كافياً. قمنا بتغيير هذا المكون لتحليل سلسلة بحث المستخدم إلى شجرة بناء جملة مجردة (AST) باستخدام مكتبة التحليل حدائق.
حددنا قواعد اللغة (PEG أو تحليل قواعد التعبير) لتمثيل بنية سلسلة البحث. تدعم القواعد النحوية كلاً من بناء جملة الاستعلام الحالي وبناء جملة الاستعلام المتداخلة الجديد ، للسماح بالتوافق المتخلف.
أ قواعد مبسطة للحصول على تعبير منطقي وصفه قواعد النحوية PEG لمحلل Parslet يظهر أدناه:
class Parser < Parslet::Parser
rule(:space) { match(" ").repeat(1) }
rule(:space?) { space.maybe }
rule(:lparen) { str("(") >> space? }
rule(:rparen) { str(")") >> space? }
rule(:and_operator) { str("and") >> space? }
rule(:or_operator) { str("or") >> space? }
rule(:var) { str("var") >> match("0-9").repeat(1).as(:var) >> space? }
# The primary rule deals with parentheses.
rule(:primary) { lparen >> or_operation >> rparen | var }
# Note that following rules are both right-recursive.
rule(:and_operation) {
(primary.as(:left) >> and_operator >>
and_operation.as(:right)).as(:and) |
primary }
rule(:or_operation) {
(and_operation.as(:left) >> or_operator >>
or_operation.as(:right)).as(:or) |
and_operation }
# We start at the lowest precedence rule.
root(:or_operation)
end
على سبيل المثال ، سلسلة بحث المستخدم هذه:is:issue AND (author:deborah-digges OR author:monalisa )
سيتم تحليلها في AST التالية:
{
"root": {
"and": {
"left": {
"filter_term": {
"attribute": "is",
"value": (
{
"filter_value": "issue"
}
)
}
},
"right": {
"or": {
"left": {
"filter_term": {
"attribute": "author",
"value": (
{
"filter_value": "deborah-digges"
}
)
}
},
"right": {
"filter_term": {
"attribute": "author",
"value": (
{
"filter_value": "monalisa"
}
)
}
}
}
}
}
}
}
استفسار
بمجرد تحليل الاستعلام في بنية وسيطة ، فإن الخطوات التالية هي:
- تحويل هذا الهيكل الوسيط إلى مستند استعلام يفهمه Elasticsearch
- تنفيذ الاستعلام ضد Elasticsearch للحصول على النتائج
ظل تنفيذ الاستعلام في الخطوة 2 كما هو بين الأنظمة القديمة والجديدة ، لذلك دعونا نتخطى الاختلافات فقط في بناء وثيقة الاستعلام أدناه.
جيل الاستعلام القديم: رسم الخرائط الخطي لشروط المرشح باستخدام فئات المرشح
كل مصطلح مرشح (على سبيل المثال: label:documentation
) لديه فصل يعرف كيفية تحويله إلى مقتطف من مستند eLasticsearch Query. أثناء توليد مستندات الاستعلام ، يتم استدعاء الفئة الصحيحة لكل مصطلح مرشح لبناء وثيقة الاستعلام الشاملة.
جيل الاستعلام الجديد: اجتياز AST المتكرر لإنشاء استعلام منطقي Elasticsearch
لقد عبرنا بشكل متكرر AST الناتج أثناء التحليل لبناء وثيقة استعلام Elasticsearch المكافئة. الهيكل المتداخل والمشغلين المنطقيين خريطة بشكل جيد إلى Elasticsearch’s استعلام منطقي مع و ، أو ، وليس المشغلين رسموا إلى يجبو يجب، و يجب أن_not بنود.
لقد قمت بإعادة استخدام اللبنات الأساسية للقطع الأصغر من توليد الاستعلام لإنشاء وثيقة استعلام متداخلة بشكل متداخل أثناء اجتياز الشجرة.
استمرارًا من المثال في مرحلة التحليل ، سيتم تحويل AST إلى وثيقة استعلام تبدو هكذا:
{
"query": {
"bool": {
"must": (
{
"bool": {
"must": (
{
"bool": {
"must": {
"prefix": {
"_index": "issues"
}
}
}
},
{
"bool": {
"should": {
"terms": {
"author_id": (
"",
""
)
}
}
}
}
)
}
}
)
}
// SOME TERMS OMITTED FOR BREVITY
}
}
مع وثيقة الاستعلام الجديدة هذه ، نقوم بتنفيذ بحث ضد Elasticsearch. يدعم هذا البحث الآن المنطق و/أو المشغلين والأقواس للبحث عن المشكلات بطريقة أكثر حبيبات.
اعتبارات
القضايا هي واحدة من أقدم والميزات الأكثر استخدامًا على جيثب. تغيير الوظائف الأساسية مثل البحث عن المشكلات ، وهي ميزة بمتوسط ما يقرب من 2000 استفسار في الثانية (QPS) – أي ما يقرب من 160 مليون استعلامات في اليوم! – قدم عدد من التحديات التي يجب التغلب عليها.
ضمان التوافق المتخلف
غالبًا ما يتم وضع إشارة مرجعية لعمليات البحث عن المشكلات ومشاركتها بين المستخدمين ، وترتبط في المستندات ، مما يجعلها مصنوعات مهمة للمطورين والفرق. لذلك ، أردنا تقديم هذه القدرة الجديدة لاستفسارات البحث المتداخلة دون كسر الاستعلامات الحالية للمستخدمين.
لقد قمنا بالتحقق من صحة نظام البحث الجديد قبل أن يصل إلى المستخدمين بواسطة:
- الاختبار على نطاق واسع: قمنا بتشغيل وحدة البحث الجديدة الخاصة بنا مقابل جميع اختبارات الوحدة والتكامل لوحدة البحث الموجودة. للتأكد من أن عقود GraphQL و REST API ظلت دون تغيير ، قمنا بإجراء اختبارات نقطة البحث على حد سواء مع علامة الميزة لتمكين نظام البحث الجديد وتعطيله.
- التحقق من صحة الإنتاج مع الشحن الداكن: بالنسبة إلى 1 ٪ من عمليات البحث عن المشكلات ، قمنا بتشغيل بحث المستخدم مقابل كل من أنظمة البحث الحالية والجديدة في وظيفة الخلفية ، وقمنا بتسجيل الاختلافات في الاستجابات. من خلال تحليل هذه الاختلافات ، تمكنا من إصلاح الحشرات وحالات الحافة المفقودة قبل أن تصل إلى مستخدمينا.
- لم نكن متأكدين في البداية كيفية تحديد “الاختلافات” ، لكننا استقرنا على “عدد النتائج” للتكرار الأول. بشكل عام ، يبدو أننا يمكن أن نحدد ما إذا كان المستخدم سوف يفاجأ بنتائج بحثه مقابل إمكانية البحث الجديدة إذا أعاد البحث عددًا مختلفًا من النتائج عند تشغيله ضمن ثانية أو أقل من بعضهم البعض.
منع تدهور الأداء
لقد توقعنا استخدام استفسارات متداخلة أكثر تعقيدًا لمزيد من الموارد على الواجهة الخلفية أكثر من الاستعلامات البسيطة ، لذلك كنا بحاجة إلى إنشاء خط أساس واقعي للاستفسارات المتداخلة ، مع ضمان عدم وجود انحدار في أداء الاستعلام القائم وأبسط.
بالنسبة إلى 1 ٪ من عمليات البحث عن المشكلات ، قمنا بتشغيل استفسارات مكافئة ضد كل من أنظمة البحث الحالية والجديدة. استخدمنا عالم، مكتبة Ruby Open المصدر المفتوحة من Github ، لإعادة تمثيل المسارات الحرجة بعناية ، لمقارنة أداء الاستعلامات المكافئة لضمان عدم وجود انحدار.
الحفاظ على تجربة المستخدم
لا نريد أن يتمتع المستخدمون بخبرة أسوأ من ذي قبل لمجرد أن عمليات البحث الأكثر تعقيدًا كانت ممكن.
تعاوننا عن كثب مع فرق المنتج والتصميم لضمان عدم انخفاض قابلية الاستخدام حيث أضفنا هذه الميزة بواسطة:
- الحد من عدد المستويات المتداخلة في استعلام إلى خمسة. من مقابلات العملاء ، وجدنا أن هذا مكان حلو لكل من الفائدة وسهولة الاستخدام.
- توفير إشارات واجهة المستخدم/UX مفيدة: نسلط الضوء على الكلمات الرئيسية و/أو في استفسارات البحث ، ونوفر للمستخدمين نفس الميزة الإكمال التلقائي لمصطلحات التصفية في واجهة المستخدم التي اعتادوا على استعلامات شقة بسيطة.
تقليل المخاطر للمستخدمين الحاليين
للحصول على ميزة تستخدمها ملايين المستخدمين يوميًا ، كنا بحاجة إلى أن نكون متعمدين بشأن طرحها بطريقة تقلل من المخاطر على المستخدمين.
قمنا ببناء الثقة في نظامنا بواسطة:
- الحد من دائرة نصف قطرها: لبناء الثقة تدريجياً ، قمنا بدمج النظام الجديد فقط في واجهة برمجة تطبيقات GraphQL وعلامة تبويب المشكلات لمستودع في واجهة المستخدم للبدء. لقد أعطانا هذا الوقت لجمع الملاحظات والرد عليها ودمجها دون المخاطرة بتجربة متدهورة لجميع المستهلكين. بمجرد أن كنا سعداء بأدائها ، قمنا بطرحه إلى قضايا لوحة القيادة و استراحة API.
- الاختبار داخليًا ومع الشركاء الموثوق بهم: كما هو الحال مع كل ميزة نقوم ببنائها في Github ، قمنا باختبار هذه الميزة داخليًا طوال فترة تطويرها عن طريق شحنها إلى فريقنا خلال الأيام الأولى ، ثم نطرحها تدريجياً إلى جميع موظفي Github. ثم شحنتها إلى الشركاء الموثوق بهم لجمع ملاحظات المستخدم الأولية.
وهناك لديك ، هكذا قمنا ببناء ، والتحقق من صحتها ، وشحننا البحث عن المشكلات الجديدة والمحسّنة!
تعليق
هل تريد تجربة هذه الوظيفة الجديدة المثيرة؟ توجه إلى مستنداتنا لمعرفة كيفية استخدامها مشغلي منطقية و أقواس للبحث عن المشكلات التي تهتم بها!
إذا كان لديك أي تعليقات لهذه الميزة ، فيرجى إسقاطنا ملاحظة على مناقشات المجتمع.
شكر وتقدير
شكر خاص لـ AJ Schuster و Riley Broughten و Stephanie Goldstein و Eric Jorgensen Mike Melanson و Laura Lindeman على ردود الفعل على العديد من التكرارات لهذا المنشور المدونة!
كتبه
اترك تعليقاً