এন্টিফিল্ডকিউরিটি কি আসলেই এই অদক্ষ?


11

আমি সত্ত্বা এপিআই-তে ভর্তি নবাগত, তবে তা নিরাময়ের চেষ্টা করছি। আমি এমন একটি সাইটে কাজ করছি যা বিভিন্ন ক্ষেত্রের সাথে সংযুক্ত বিভিন্ন ধরণের সামগ্রী ব্যবহার করে; অভিনব কিছু না। সুতরাং, যখন আমি এন্ট্রিগুলির একটি সেট পুনরুদ্ধার করতে চাই, তখন আমি আমার অজ্ঞতাবশত সরাসরি ডাটাবেসে ডেকে এই জাতীয় কিছু করে থাকি:

$query = db_select('node', 'n')->extend('PagerDefault');
$query->fields('n', array('nid'));
$query->condition('n.type', 'my_content_type');

$query->leftJoin('field_data_field_user_role', 'role', 'n.nid = role.entity_id');
$query->condition('role.field_user_role_value', $some_value);

$query->leftJoin('field_data_field_withdrawn_time', 'wt', 'n.nid = wt.entity_id');
$query->condition('wt.field_withdrawn_time_value', 0);

$query->orderBy('n.created', 'desc');

$query->limit(10);

$result = $the_questions->execute()->fetchCol();

(হ্যাঁ, আমি সম্ভবত এই রেখাগুলির একগুচ্ছ একক $the_questions->বিবৃতিতে ভেঙে দিতে পারলাম ; এখনই এটিকে উপেক্ষা করুন ignore)

এন্টিফিল্ডকিউরি দিয়ে এটি পুনরায় লেখার চেষ্টা করে আমি এনেছি:

$query = new EntityFieldQuery();
$query
  ->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'my_content_type')
  ->fieldCondition('field_user_role', 'value', $some_value)
  ->fieldCondition('field_withdrawn_time', 'value', 0)
  ->propertyOrderBy('created', 'desc')
  ->pager(10);

$result = $query->execute();

if (isset($result['node'])) {
    $result_nids = array_keys($result['node']);
}
else {
    $result_nids = array();
}

যা আমাকে পছন্দসই ফলাফল দেয় এবং অবশ্যই অনেক সুন্দর।

সুতরাং, এখন আমি অভিনয় সম্পর্কে ভাবছি। শুরু হিসাবে, আমি কোডের সেই বিটগুলির প্রত্যেকটিকে একটি নির্বোধ for()লুপের মধ্যে ফেলে দিই , time()কার্যকর করার আগে এবং পরে ক্যাপচার করে । আমি প্রতিটি সংস্করণটি খুব বড়-বড় নয় এমন একটি ডাটাবেসের মাধ্যমে 100 বার চালিত করি এবং এরকম কিছু পাই:

  • প্রত্যক্ষ সংস্করণ: 110 ম্যাসি
  • EFQ সংস্করণ: 4943 এমসেক

স্পষ্টতই আমি পরীক্ষাটি পুনরায় চালানোর সময় বিভিন্ন ফলাফল পাই তবে ফলাফল একই ধারাবাহিকভাবে একই বলপার্কে থাকে।

বাবা। আমি কি এখানে কিছু ভুল করছি, বা এটি কেবল ইএফকিউ ব্যবহারের ব্যয়? আমি সামগ্রীর ধরণের ক্ষেত্রে বিশেষ কোনও ডাটাবেস টিউনিং করিনি; এগুলি হ'ল সাধারণ, ফর্ম-ভিত্তিক উপকরণের প্রকারের সংজ্ঞা দিয়ে আসে what কোন চিন্তা? ইএফকিউ কোডটি অবশ্যই ক্লিনার, তবে আমি সত্যিই মনে করি না যে আমি 40x পারফরম্যান্স হিট করতে পারব।


3
আপনি উভয় উত্পন্ন স্কয়ার প্রশ্ন জিজ্ঞাসা করতে পারেন?
আন্দ্রে বাউমিয়ার

1
দেখুন এই এক আপনি যদি নিশ্চিত কিভাবে একটি EFQ এর এসকিউএল নামা নও
ক্লাইভ

2
ঠিক আছে, এখানে অগ্রগতি হচ্ছে: এখানে যা চলছে তা হচ্ছে আমার সাইটে নোড অ্যাক্সেসের নিয়ম রয়েছে যা ক্যোয়ারীর আকারকে কিছুটা বাড়িয়ে তুলছে। এগুলি স্বয়ংক্রিয়ভাবে EFQ ক্যোয়ারিতে প্রয়োগ করা হচ্ছে (যদিও কোয়েরিতে কোনও নেই ->addTag('node_access')??)। আমি নোড_একসেস ট্যাগ দিয়ে "সরাসরি" ক্যোয়ারীটি পুনরায় পুনরায় রচনা করি এবং মৃত্যুদন্ড কার্যকর করার সময়টি আরও অনেক কাছাকাছি: EFQ- র সময়টি সরাসরি পদ্ধতির চেয়ে কেবলমাত্র 2 টির বেশি কারণ এটি আপেক্ষিক এসকিউএলকে উভয়ই পাম্প করে চলেছে বলে যুক্তিসঙ্গত বলে মনে হয় (কোনটি লোকেরা যদি এখনও যত্ন করে তবে আমি পোস্ট করতে পারি)। (পরবর্তী মন্তব্যে সহ্য করুন ....)
জিম মিলার

সুতরাং এখন প্রশ্ন, আমার ধারণা, আমি কেন স্বয়ংক্রিয়ভাবে EFQ সংস্করণে নোড_একসেস স্টাফ পাচ্ছি? আমি ভেবেছিলাম আপনার অ্যাডট্যাগ () ধারাটির মাধ্যমে স্পষ্টভাবে এটি জিজ্ঞাসা করতে হবে ??
জিম মিলার

উত্তর:


10

EntityFieldQueryশ্রেণী হিসেবে দক্ষ হিসেবে তার প্রয়োজনীয়তা এটা হতে অনুমতি নেই। ক্ষেত্রের ডেটা সংরক্ষণ করার জন্য কোনও নোএসকিউএল ইঞ্জিন ব্যবহার করে এমনদের সাথেও এটি কোনও ফিল্ড স্টোরেজ ক্লাসের সাথে সামঞ্জস্যপূর্ণ হওয়া দরকার, যেমন মোংগোডিবি ব্যবহার করে । সেই কারণে, EntityFieldQueryসরাসরি ডাটাবেসটিকে জিজ্ঞাসা করতে পারে না, কারণ বর্তমান ক্ষেত্রের স্টোরেজ ব্যাকএন্ডটি কোনও এসকিউএল ডাটাবেস একেবারেই ব্যবহার করতে পারে না।

এমনকি ক্ষেত্রে ক্ষেত্রে ক্ষেত্রের স্টোরেজ তার ডেটা সঞ্চয় করতে একটি এসকিউএল ইঞ্জিন $query->leftJoin('field_data_field_user_role', 'role', 'n.nid = role.entity_id'); $query->condition('role.field_user_role_value', $some_value);ব্যবহার করে, EntityFieldQueryশ্রেণীর সমতুল্যটির জন্য এটির প্রয়োজন হয়:

  • ক্ষেত্রের নাম থেকে ডাটাবেস সারণির নাম তৈরির কোড
  • সত্তার ডেটাযুক্ত টেবিলের সাথে ক্ষেত্রের ডেটাযুক্ত সারণিতে যোগদানের জন্য শর্তটি তৈরি করার কোড
  • ক্ষেত্রের ডেটাযুক্ত ডাটাবেস সারির নাম তৈরির কোড

পার্থক্যটি তাত্ক্ষণিকভাবে দৃশ্যমান হয়: একটি ক্ষেত্রে আপনি তিনটি লিটারেরাল স্ট্রিং ব্যবহার করছেন, অন্য ক্ষেত্রে এমন কোড রয়েছে যা (সবচেয়ে সহজ ক্ষেত্রে) স্ট্রিংটি স্ট্রিং করছে।

কোড সম্পর্কে আপনার মন্তব্য অনুসারে যা ব্যবহারকারীদের ক্ষেত্রগুলি অ্যাক্সেস করার অনুমতি আছে কিনা তা পরীক্ষা করে, আপনি EntityFieldQueryক্লাসটি ব্যবহার করে নিম্নলিখিত লাইনটি কোডটিতে ব্যবহার করে বাইপাস করতে পারেন ।

$query->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');

আপনি যদি ড্রুপাল 7.15 বা তার বেশি ব্যবহার করেন তবে এটি কাজ করে; পূর্ববর্তী সংস্করণগুলির জন্য আপনার নিম্নলিখিত কোডটি ব্যবহার করা উচিত।

$account = user_load(1);
$query->addMetaData('account', $account);

যথারীতি, কোডটি ব্যবহারকারীর যে তথ্যটিতে ব্যবহারকারীর অ্যাক্সেস না থাকা উচিত তা যদি দেখাতে পারে তবে আপনার অ্যাক্সেসের অনুমতিটি বাইপাস করা উচিত নয়। এটি একটি অপ্রকাশিত নোড কেবল তখনই অপ্রকাশিত নোডগুলি দেখার অনুমতি প্রাপ্ত ব্যবহারকারীদের দেখানো হলে দ্রুপাল থেকে করা সমান। যদি কোডটির উদ্দেশ্য হয়, উদাহরণস্বরূপ, এমন কিছু সত্তা নির্বাচন করা যা ধারাবাহিকভাবে মুছে ফেলা হয় (যেমন ক্রোন কার্যের সময়), তবে অ্যাক্সেস নিয়ন্ত্রণকে পাশ কাটিয়ে কোনও ক্ষতি করতে পারে না এবং এটি এগিয়ে যাওয়ার একমাত্র উপায়।


আমার অবশ্যই স্বীকার করা উচিত যে আমি সম্ভবত সঠিক নই, যেহেতু প্রথম ক্যোয়ারী একটি ->extend('PagerDefault');
পেজারও

ওফ, আপনি ঠিক বলেছেন।
কিমলালুনো

এটি আমাকে সত্যই আগ্রহী করে তুলেছে, তাই আমি উপরের পরীক্ষার লাইনের সাথে কিছু চেষ্টা করছি এবং সংখ্যার বিশাল পার্থক্যটি নিশ্চিত করতে পারছি না ... কেউ কি এটিও চেষ্টা করতে পারেন, দয়া করে?
মোজিজিস

সুতরাং, কেবল তা নিশ্চিত করার জন্য: EFQ সর্বদা কল করে সাইটটির নোড অ্যাক্সেসের নিয়মগুলিকে সর্বদা অনুরোধ করে যতক্ষণ না আপনি এটিকে ঘটতে থেকে বিরত রাখতে কিছু না করেন (উপরে বর্ণিত হিসাবে)। রাইট?
জিম মিলার

@ জিমমিলার এটি সঠিক, এবং এটি কারণেই দ্রুপাল .1.১৫-তে "ড্যাঙ্গারওস_আসিসিএস_সিইসি_সিইকি_ওপিএইচ" ট্যাগ যুক্ত করা হয়েছে।
কিমলালুনো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.