দ্রুত একক ক্ষেত্রের মান সংরক্ষণ করা


19

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

field_attach_updateএকটি পোস্টে উল্লেখ করা হয়েছিল , তবে এটি খুব দ্রুত নয়।

সম্পাদনা: এই নোড টাইপের উপর বেশ জটিল দৃষ্টিভঙ্গি নির্মিত হয়েছে, তবে আমি আপডেট করতে চাইলে এই ক্ষেত্রে কাজ করছে না।

উত্তর:


30

আমি অবশ্যই যেতে চাই field_attach_update

ধারণাটি সহজ। কেবল নোডটি লোড করুন এবং ফিল্ড_আটাচ_আপডেট ব্যবহার করে এটি সংরক্ষণ করুন।

উদা:

$node = node_load($nid);
$node->field_name[LANGUAGE_NONE][0]['value'] = 'New value';
field_attach_presave('node', $node);
field_attach_update('node', $node);
  // Clear the static loading cache.
entity_get_controller('node')->resetCache(array($node->nid));

এটি কোনও টাইমস্ট্যাম্প বা নোড_সেভ সাধারণত অনুরোধ করে এমন কোনও হুক পরিবর্তিত হবে না। নোড লোড করা কিছু হুককেও ডেকে আনবে সম্ভবত এটি এতটা দক্ষ নয়।

আপনার যদি নিড থাকে এবং নোডের কাঠামোটি যদি মৃত সহজ হয় তবে আপনি এটিও এটি করতে পারেন:

 $node = new stdClass();
 $node->nid = $nid; // Enter the nid taken. Make sure it exists. 
 $node->type = 'article';
 $node->field_name[LANGUAGE_NONE][0]['value'] = 'New value';
 field_attach_presave('node', $node);
 field_attach_update('node', $node);
  // Clear the static loading cache.
 entity_get_controller('node')->resetCache(array($node->nid));

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

আপডেট: দেখা যাচ্ছে যে field_attach_presave()অন্যান্য মডিউলগুলি ফিল্ড ইনপুটটি সঠিকভাবে প্রক্রিয়া করতে দেওয়ার জন্যও আপনাকে কল করা উচিত । উদাহরণস্বরূপ, ফাইল মডিউলটি এই হুক ব্যবহার করে স্থিতিতে ফাইলের স্থিতি সেট করতে ব্যবহার করে। আমি উপরে আমার 2 উদাহরণ আপডেট করেছি।


আমার কাছে নিড আছে তবে নোডের জন্য কাঠামো এতটা সহজ নয়, তবে আমি যে ক্ষেত্রটি আপডেট করতে চাই তা মৃত সহজ। বিদ্যমান নোডের জন্য কেবলমাত্র একটি ক্ষেত্র স্থাপন (এনআইডি দ্বারা চিহ্নিত কিন্তু লোড নয়) এবং তারপরে কলিং থেকে আমি কী আশা করতে পারি field_attach_update?
ইলোয়ার

4
যেহেতু এটি সত্তা কোয়েরিটি ব্যবহার করে তা হ্রাস পাচ্ছিল। থেকে সুইচিং তাই node_saveকরতে field_attach_updateএবং থেকে EntityFieldQueryথেকে db_query_rangeবেশ ফলপ্রসূ হয়। 3 ঘন্টা আপডেট থেকে 40 মিনিট পর্যন্ত।
ইলোয়ার

2

যদি আপনি স্ট্যান্ডার্ড ইভেন্ট এবং ক্রিয়াগুলি না ঘটে ক্ষেত্রের ডেটা সংরক্ষণ করতে না চান তবে আপনি drupal_write_record ব্যবহার করতে পারেন ।

1 এর আইডি সহ টাইপ নিবন্ধের নোডের জন্য বডি ফিল্ডে হ্যালো ওয়ার্ল্ড toোকানোর উদাহরণ এখানে।

$values = array(
  'entity_type' => 'node',
  'bundle' => 'article',
  'entity_id' => 1,
  'revision_id' => 1,
  'language' => 'und',
  'delta' => 0,
  'body_value' => 'HELLO WORLD',
  'body_summary' => '',
  'body_format' => 'filtered_html',
);
drupal_write_record('field_data_body', $values);
drupal_write_record('field_revision_body', $values);

যদি আপনার সাইটটি বহুভাষিক হয় তবে আপনি 'আন' এর পরিবর্তে 'এন' বা আপনার সামগ্রীর ভাষা ব্যবহার করতে চাইবেন।

আপনি যদি পুনর্বিবেচনা করছেন, আপনাকে সঠিক সংশোধন আইডি toোকাতে সতর্কতা অবলম্বন করতে হবে, অন্যথায় আপনি কেবল সত্তা_আইডের সমান মান সন্নিবেশ করতে পারেন।

এই ডেটাটি কীভাবে ফিল্ড_ডেটা_ * এবং ক্ষেত্র_দর্শন_ * দুটি সারণিতে isোকানো হয়েছে তা দ্রষ্টব্য। আপনার পছন্দ অনুযায়ী সাইটটি কাজ করে তা নিশ্চিত করার জন্য আপনার উভয়ের মধ্যে প্রবেশ করা উচিত।

এটি চালানোর পরে আপনাকে ক্ষেত্রগুলির জন্য ক্যাশেগুলি সাফ করতে হবে আপনার ক্যাচিং কীভাবে সেটআপ হচ্ছে তার উপর নির্ভর করে show


2

এই জাতীয় একটি সহজ আপডেটের জন্য যেখানে প্রচুর নোড আপডেট করা দরকার, আমি সর্বদা একটি মাইএসকিউএল আপডেট বিবৃতি ব্যবহার করি। হ্যাঁ, ক্যাচিংয়ের বিষয়টি বিবেচনা করা দরকার তবে আপনার কাজ শেষ হওয়ার পরে আপনি কেবল ক্যাশে ফ্লাশ করতে পারেন এবং এটি সব ভাল। আপনার অবশ্যই অবশ্যই ডেটা কাঠামোর সাথে পরিচিত হওয়া দরকার তবে এটি দ্রুপাল in-এ তুলনামূলক সহজ simple (যদিও দ্রুপাল al-এ ভয়াবহ)


প্রজেক্টটি ড্রুপাল for এর জন্য তৈরি করা হয়েছিল পরে আমার মডিউলের সমস্ত অংশগুলি দ্রুপাল ডিবি কাঠামোতে সরাসরি মান পড়ার জন্য এবং বর্গ কোয়েরি হিসাবে অনুসন্ধান করার জন্য এনটিটিফিল্ডকিউয়ার্সের চেয়ে তাত্ক্ষণিকভাবে অনুসন্ধান করার জন্য তৈরি করা হয়েছিল।
এলওর

2

আমিও প্রস্তাব দিচ্ছি field_attach_update, এবং সরাসরি এসকিউএল কোয়েরি নয়, কারণ এসকিউএল নোড ক্যাশে অবজেক্টটি আপডেট করে না এবং আপনার পরবর্তী node_loadক্ষেত্রে আপনি আপডেট করা ক্ষেত্রের মানটি লোড করতে পারবেন না, আপনি পুরানো মানটি লোড করবেন

field_attach_update ডাইরেক্ট এসকিউএল কোয়েরির চেয়ে অনেক ভাল is


আয়েশ কে stdClassলোড না করে অবজেক্ট হিসাবে নোড তৈরির পরামর্শ দিয়েছিলেন । আপনি কি জানেন যে আমি যদি সমস্ত ক্ষেত্র সেট না করে এইভাবে নোড আপডেট করার চেষ্টা করি তবে কী হতে পারে? এগুলি কি নাল বা ডিফল্ট দিয়ে ওভাররাইট করা হবে? প্রক্রিয়া আপডেটের দ্বারা এগুলি উপেক্ষা করা যেতে পারে?
ইলোয়ার

1
আইয়েশ পদ্ধতিতে (একটি নতুন স্টাডক্লাস ইত্যাদি ...) দ্বারা সরাসরি কোনও নোড সংরক্ষণ করা সম্ভব কেবলমাত্র ইউআই প্রয়োজনীয় ক্ষেত্রগুলিতে বৈধতা দেয়
পিকো 34

আমি সমস্ত ক্ষেত্র সেট না করে এই পদ্ধতির সাথে নোড আপডেট করার চেষ্টা করব এবং কী হবে তা যাচাই করব। মডিউল আপডেট পদ্ধতি (ব্যাচ) এ নোডগুলি আপডেট করার জন্য এটি দ্রুততম পদ্ধতি হতে পারে।
ইলোয়ার

2

অন্যান্য উত্তরগুলিতে উল্লিখিত সমস্ত পদ্ধতির চেষ্টা করেও আমি খুব ধীর আপডেটের সময় পেয়েছি (20+ ক্ষেত্র সহ নোডের 700.000 নোডের জন্য প্রায় 7 দিন) আমি এই নিবন্ধটি না পাওয়া পর্যন্ত: http://www.drupalonwindows.com/en/ ব্লগ / শুধুমাত্র আপডেট-পরিবর্তিত ক্ষেত্র-বা-বৈশিষ্ট্য-সত্তা-দ্রুপাল

একটি হুক_আপডেটে নীচের কোডটির মতো কিছু প্রয়োগ করার পরে আমি আপডেটের সময়টিকে 2 ঘন্টার মধ্যে কমিয়ে দিয়েছি, যা আমি মনে করি এটি পরিচালনাযোগ্য।

if (!isset($sandbox['storage']['nids'])) {
    $sandbox['storage']['nids'] = [];
    $query = 'SELECT {nid} FROM node WHERE type = \'article\';';
    $result = db_query($query)->fetchCol();
    if ($result) {
      $sandbox['storage']['nids'] = $result;
      $sandbox['storage']['total'] = count($sandbox['storage']['nids']);
      $sandbox['storage']['last_run_time'] = time();
      $sandbox['progress'] = 0;
    }
  }

  $amount = 300;
  $nids = array_slice($sandbox['storage']['nids'], 0, $amount);

  if (!empty($nids)) {
    $nodes = node_load_multiple($nids, [], TRUE);
    foreach ($nodes as $node) {
      // Lets manipualte the entity.
      $article_wrapper = UtilsEntity::entity_metadata_wrapper('node', $node);
      // Eventual logic here.

        // Field to update
        $article_wrapper->my_field = 'my_value';
        $article_wrapper->save();

    $sandbox['progress']++;
    }
    $sandbox['message'] = 'Runs left: ' . (($sandbox['storage']['total'] - $sandbox['progress'])/$amount) . ' Progress: ' . (($sandbox['progress'] * $amount)/$sandbox['storage']['total']) . '%';
    $sandbox['storage']['last_run_time'] = time();
    unset($nids);
  }
  $sandbox['storage']['nids'] = array_slice($sandbox['storage']['nids'], 100, count($sandbox['storage']['nids']));
  if (!empty($sandbox['storage']['total'])) {
    $sandbox['#finished'] = ($sandbox['storage']['total'] - count($sandbox['storage']['nids'])) / $sandbox['storage']['total'];
  }
  return $sandbox['message'];

1

এমনকি আমার কাছে নির্দিষ্ট সামগ্রীর ধরণের সমস্ত নোডের জন্য একটি ক্ষেত্র আপডেট করার অনুরোধ ছিল। আমি নোড_ লোড_মલ્ટ িপল এবং ফিল্ড_আটাচ_আপডেট ব্যবহার করেছি

$nodes = node_load_multiple(array(), array('type' => 'content_type_name'));
foreach ($nodes as $node) {
  $node->field_name['und'][0]['value'] = 'field value';
  field_attach_update('node', $node);
}

আমি এটি ড্রাশ দিয়ে চালিয়েছি এবং এটি বেশ দ্রুত ছিল।


0

আপনি কি MySQL ব্যবহার করে সরাসরি ডেটাবেজে এই আপডেটগুলি করার কথা বিবেচনা করেছেন? আপনি যা চান তা অর্জনের এটি সম্ভবত সহজতম এবং দ্রুততম উপায়।

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

বিষয়বস্তু_প্রকার_আমার_প্রফল ফাইল সেট করুন field_type_of_member_value'' সংস্থা 'WHERE field_type_of_member_value=' কোম্পানী ';

এছাড়াও, চেকআউটটি মাইএসকিউএল দিয়ে শুরু করুন


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

গুগ পয়েন্ট আমি আমার প্রাথমিক উত্তরে একটি সাধারণ উদাহরণ যুক্ত করেছি।
বাইসনবলু

হ্যাঁ, আমি কোনও টেবিলের কোনও রেকর্ড আপডেট করার জন্য এসকিউএলকে যথেষ্ট ভাল জানি। এটি সমস্যা নয়। সমস্যাটি হচ্ছে, ড্রুপাল যেভাবে ডেটা সঞ্চয় করে (বিশেষত মেটা-ডেটা) তার সাথে আমি যথেষ্ট পরিচিত নই। এই জাতীয় সিস্টেমে সর্বদা প্রচুর ক্যাচিং, সংরক্ষণ করা ইত্যাদি থাকে, তাই এটিকে সর্বনিম্ন স্তরে আপডেট করার ফলে কিছুটা ত্রুটি বিচলিত হতে পারে (সর্বদা নয়)। সুতরাং এটি যদি এ আসে, আমি এটি সর্বনিম্ন স্তরে করার চেষ্টা করব এবং আমি কিছু সত্যিকারের জগাখিচির জন্য প্রস্তুত থাকব।
ইলোয়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.