اذهب إلى المحتوى

Sam Ahw

الأعضاء
  • المساهمات

    1388
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    16

كل منشورات العضو Sam Ahw

  1. يمكنك بشكل مختصر استخدام readdirSync من المكتبة fs ضمن node.js بالشكل التالي: بما أنه يمكن الوصول إلى المجلّد الأساسي وليكن اسمه target_folder: const { readdirSync } = require('fs') const all_directories = target_folder => readdirSync(target_folder, { withFileTypes: true }) .filter(e => e.isDirectory()) .map(e => e.name) بحيث تمكننا المكتبة من اختبار محتويات المجلّد في حال كانت مجلّدات أيضاً (أو فيها محتويات أخرى) ونقوم بإعادة اسم هذا العنصر وتجميعها ضمن المتغيّر النهائي: all_directories ولكن يجب عليك الانتباه إلى الحصول على المسار المطلق absolute بالشكل التالي: require('path').resolve(__dirname, file)
  2. تأكد من إعدادات npm من خلال npm config، ففي حال كانت قيمة production هي true، سيقوم بتجاهل dev depencencies بشكل دائم. أو حتى في حال كان لديك المتغيّر NODE_ENV يساوي production. يمكنك تشغيل الأمر التالي: npm config get production ولتغيير القيمة إلى false: npm config set -g production false من المحتمل في بعض الأحيان في حال قمت بنسخ ملفات من مشروع آخر أن يتواجد بعض الإعدادات المحفوظة ضمن الملف package-lock.json، في حال كان يحوي قيم production أيضاً يجب عليك حذف هذا الملف وسيتم إعادة توليده عند عملية التحميل التالية. كما ويمكنك تجربة الاختصار التالي للتحميل بوضع العلامة -D: npm i -D <names>
  3. إن timestamps في mongodb هي ثابتة ومرتبطة بشكل مباشر بتوقيت unix. أما عند التعامل معها مع الكود البرمجي مثلاً node.js يقوم المفسّر في node بأخذ قيمة التاريخ حسب timezone الجهاز الذي يقوم بالتنفيذ عليه. مثلاً في حال كانت منطقتك الزمنية UTC+2 وهكذا. لذلك قد تجد اختلاف بين القيمة التي يتم تخزينها في mongodb والقيمة التي يتم إظهارها ضمن node.js لذلك يمكن معالجة هذه المشكلة إما بالتعامل دوماً مع التوقيت حسب Unix كمرجع ثابت للتوقيت بين قاعدة البيانات وخادم الويب لديك، أو عن طريق تعديل التوقيت بالشكل المناسب لك (أخذ منطقتك الزمنية على سبيل المثال كمرجع ثابت) وحفظها أثناء إدخال البيانات إلى القاعدة. ولتحقيق ذلك تم إيجاد عدة حلول، منها مكتبة يمكنك إضافتها لتعمل مع mogoose وتدعى moment-timezone ويمكنك استخدامها كالتالي: const moment = require('moment-timezone'); const myDate = moment.tz(Date.now(), "نضع هنا المنطقة الزمنية"); ثم في ال schema نكتبها بالشكل التالي: const someSchema = new Schema( { ... anyDate: {type: Date, default: myDate}, ... } ); ولمعرفة اسماء المناطق الزمنية يمكنك التوجه إلى التوثيق الرسمي ل moment js.
  4. يمكنك إجراء mongodump على المجموعة في قاعدة البيانات الأولى (المصدر) ثم استعادتها ضمن قاعدة البيانات الثانية (الهدف) من خلال mongorestore، بالشكل التالي: mongodump -d sourceDatabase -c yourCollectionName ولاستعادتها: mongorestore -d destDb -c collectionName dump/collectionName.bson حيث باتباع هذه الطريقة يمكنك الاستفادة من الضغط zip وفك الضغط scp في حال كانت المجموعة كبيرة الحجم: zip db.zip db/* -r أما في حال كنت تستخدم أي لغة برمجة، يمكنك إجراء عملية النسخ بشكل مبسّط جداً من خلال حلقة تكرارية ومصفوفة يمكنك استخدامها أينما ترغب.
  5. يجب عليك تحديث النسخة الحالية من npm من خلال: npm install npm -g --ca="" أو في حال أردت إبقاء النسخة الحالية، يجب عليك تنفيذ الأمر التالي والذي يقوم بإخبار npm باستخدام مسجلات معروفة known registars: npm config set ca "" كما يمكنك أيضاً العودة إلى التوثيق الرسمي وقراءة بعض الخطوات التي تم شرحها ليتم تطبيقها ضمن مختلف البيئات فيما يتعلق بالتحديث و self signed certificates. من الحلول الأخرى أيضاً: تحديث node.js وتحديث npm بشكل عام: npm update npm -g أو يمكنك تغيير رابط الحصول على المسجلات إلى http بالشكل التالي: npm config set registry="http://registry.npmjs.org/"
  6. يمكنك استخدام apache في تخديم صفحات PHP الموجودة في مشروعك من خلال استخدام proxyPass ضمن ملف httpd.conf في apache والتي ستقوم باستقبال جميع الطلبات من مسار محدد وتوجّهه إلى مشروعك: ProxyPass /project http://localhost:8000 ثم يجب عليك إزالة التعليق من الأسطر التالية: LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so وبعدها سيتم إعادة توجيه أي طلبات من المسار project إلى مشروعك المبني ضمن node.js والذي يجب أن يكون أيضاً على نفس المنفذ الذي قمنا بتعريفه ضمن proxyPass: var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Node js back-end is running, port = 8000 '); }).listen(8000, '127.0.0.1'); أما بقية الطلبات والتي هي تابعة إلى PHP فسيتم تخديمها من قبل Apache
  7. يمكنك استبدال الإشارات في حال وجودها ضمن اسم المستخدم أو كلمة المرور بالترميز الذي يدل عليها. على سبيل المثال، يمكنك كتابة الرمز (%40) بدلاً من @ ضمن كلمة المرور فيصبح الاتصال على الشكل التالي: //بفرض كلمة المرور هي my@password mongoClient.connect("mongodb://username:my%40pssword@host:port/dbname?authSource=admin", { useNewUrlParser: true }, function(err, db) { } ); وفي حال كنت تستخدم node.js يجب عليك أيضاً تمرير التالي ضمن تابع الاتصال: {uri_decode_auth: true} أما الاتصال عن طريق mongoose فمكن أن يتم بالشكل التالي: mongoose.connect('mongodb://localhost/mydatabase', {user: 'usr', pass: 'any@password@'}, callback);
  8. لقد تمّت إزالة الأوامر المباشرة المتعلّقة ب mongodb من homebrew-core, لذلك يجب عليك إزالة النسخة الحالية من خلال تنفيذ الأوامر التالية: brew services stop mongodb brew uninstall mongodb ثم التحميل من خلال tap لنستطيع إضافة mongodb: brew tap mongodb/brew وبعدها: brew install mongodb-community brew services start mongodb-community
  9. بما أن محرر الأوامر في mongodb تفاعلي يمكنك إجراء الأوامر التالية: mongo dbname << EOF > output.json db.collection.find().pretty() EOF أو بإمكانك الاستفادة من جافاسكريبت لأخذ نتيجة find وتحويلها إلى JSON: mongo dbname mongoCommands.js > output.json بعد أن يتم وضع الأمر ضمن الملف mongoCommands.js كالتالي: printjson( db.collection.find().toArray() )
  10. لقد قمت بتمرير المتغيرات إلى للدالة spawn بشكل غير صحيح. قمن التوثيق الرسمي الدالة spawn لها الشكل التالي: spawn( command, args, options ) والتي تقوم بإنشاء عملية جديدة مع تمرير المتغيرات. والمتغيّرات args لها القيمة (مصفوفة فارغة) بشكل افتراضي. أما المتغيّر الثالث options يستخدم لتمرير خصائص إضافية لهذه الدالة والتي تكون قيمتها بشكل افتراضي كالتالي: { cwd: undefined, env: process.env } لذلك في حالتك يجب تمرير القيم كخصائص ضمن env في مكان المتغيّر options وليس args، بحيث تصبح كالتالي: spawn( 'node', ['server.js'], { env: { ...process.env, NODE_ENV: 'test' } }}) بحيث يتم استخدام spread operator أو (...) لأخذ بقية القيم من process.env أو يمكنك بشكل مماثل تعريف متغيرات البيئة والدلالة عليها كالتالي: var productionEnv = process.env; productionEnv.NODE_ENV = 'production';
  11. يجب عليك تغيير صلاحيات الوصول إلى المجلّد، أولاً يجب التأكد من المستخدم المالك owner المجلد: ls -la /usr/local/lib/node_modules وغالباً في حال يتم رفض الوصول إلى المجلّد هذا يعني أن المالك هو root، وللتأكد من المستخدم الحالي يمكنك تنفيذ: whoami //أو id -un ثم يمكنك تغيير المالك owner من خلال تنفيذ الأمر: sudo chown -R [owner]:[owner] /usr/local/lib/node_modules أو sudo chown -R ownerName: /usr/local/lib/node_modules كما ينصح البعض أيضاً بإجراء هذه التعديلات على كل من المجلدات التالية في حال استمرار المشكلة: sudo chown -R $USER /usr/local/lib/node_modules/ sudo chown -R $USER /usr/local/bin/ sudo chown -R $USER /usr/local/share/
  12. يمكن التحكّم بالخادم من خلال ما يقدّمه node.js من مكاتب بشكل افتراضي دون الحاجة لتحميلها وهي process و child_process. حيث تستطيع إعادة التشغيل عند وصول حدث معيّن كالتالي: var process = require('process'); var cp = require('child_process'); var server = cp.fork('server.js'); console.log('Server started'); //عند وصول حدث معيّن server.kill(); server = cp.fork('server.js'); حيث من المهم إنشاء نسخة عند تشغيل الخادم من خلال cp.fork، وإلا لن نستطيع إعادة تشغيل الخادم بعد إيقافه. أما فيما يتعلّق ب pm2 فهذه الأوامر تتعامل بشكل مباشر مع الخادم (أي ملف server.js) وليس لها أي علاقة بمدير الحزم لذلك يجب عليك الأخذ بعين الاعتبار إما إيقاف وتشغيل الخادم من هنا أو من خلال ما يتحكّم به pm2
  13. إن pass في لغة بايثون هي باختصار القيمة null (أو عدم وجود قيمة). بحيث لا يتم تجاهلها من قبل المفسّر ولا تسبب أي خطأ وإنما فقط يتم التعرّف على مكان وجودها. يتم استخدامها على سبيل المثال في حال كنا نريد وضع تابع معيّن ولكن لا نرغب بإضافة أي كود ضمنه، نقوم بكتابة pass للاحتفاظ بمكانه وإضافة أي كود ضمنه في المستقبل. مثال: def addition(num1, num2): pass addition(2, 2) أو عندما نريد تجاهل شرط معيّن مثلاً من شروط if: def display(number): if number is 2: pass else: print ("Number: ", number) display(2) display(3) بحيث عندما يتم الآن تمرير الرقم 2 لن يحدث شيء ولا يوجد أي معالجة له، أما عدى ذلك فسيتم طباعة الرقم.
  14. بما أن الأقسام منفصلة عن بعضها وتتشارك نوعاً ما ببنية الكود من الممكن حدوث تضارب كبير في حال تم تجميع كل الـ schema لجميع قواعد البيانات التي لديك ضمن مكان واحد، وبذلك سيصبح المشروع معقّد جداً ولن تستطيع تمييز الخطأ عند حدوثه، لذلك في حال كان كل قسم يحوي مكتباته الخاصة أي ملف (package.json) يمكنك تحميل mongoose في هذه الأقسام بشكل منفصل والتعامل مع الاتصال وبنية schema لكل قاعدة بيانات على حدى. وبالتالي يمكنك إنشاء module خاص بالاتصال ضمن كل قسم كالتالي (وليكن ملف اتصال القسم الأول sub_project1_connect.js): var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/sub_project1'); module.exports = exports = mongoose; وهكذا لبقية الأقسام، ثم نقوم بإنشاء ملف واجهة interface لهذه الاتصالات بحيث يقوم بتجميعها لسهولة الوصول إليها لاحقاً: var mongoose = require("./sub_project1_connect.js"); الآن يمكنك في أي مكان في الكود وضمن أي قسم من تضمين ملف الاتصال الموافق لقاعدة البيانات التي ترغب بالتعامل معها وسيتم بشكل تلقائي إنشاء نسخة mongoose من ذلك الاتصال وبالتالي تحصل على بنية أفضل للملفات وسهولة أكبر في التعامل المباشرة مع قواعد البيانات و ال schema الموجودة لديك. أما في حال رغبت باستخدام التابع createConnection فيجب عليك عندها إنشاء model خاص بكل اتصال بالشكل التالي: var first_con = mongoose.createConnection('mongodb://localhost/sub_project1'); var second_con = mongoose.createConnection('mongodb://localhost/sub_project2'); // قاعدة البيانات الأولى var Model_project1 = first_con.model('Model', new mongoose.Schema({ .... })); // قاعدة البيانات الثانية var Model_project2 = second_con.model('Model', new mongoose.Schema({ ... }));
  15. الفرق الأساسي بين الدوال هو البارامترات التي يتم استخدامها وبالتالي طريقة عمل كل منها: fs.write(fd, buffer, offset, length, position, callback) في الدالة fs.write يجب عليك انتظار callback حتى يتم تأكيد كتابة buffer على القرص الصلب. أما في الدالة fs.writeFile: fs.writeFile(filename, data, [encoding], callback) يتم كتابة جميع البيانات دفعة واحدة، ولا يمكنك إجراء عمليات كتابة منفصلة عن بعضها ضمن الملف. أما في fs.createWriteStream: fs.createWriteStream(path, [options]) هنا نلاحظ من البارامترات أنه لا يجب أن ننتظر أي callback عند إجراء العملية.
  16. بدءً من النسخة الخامسة من mongoose، أصبح بالإمكان تعطيل هذه الخاصية بشكل كامل عن كل المجموعات التي يتم إنشائها من خلال إضافة السطر التالي بعد إجراء الاتصال: mongoose.pluralize(null); وعندها لن تحتاج إلى إعادة تسمية كل مجموعة على حدى.
  17. بهذه الحالة يجب عليك تغيير بنية قاعدة البيانات، لأنه إذا أردت تفصيل الطلبات للحصول على قيم qis لكل طلب أو (مادة) يجب إضافة سجلات منفصلة عند كل طلب ويتم وضعة الكمية qis المفصّلة ضمن هذا السجل، ثم بعدها يمكنك جمع هذه القيم لطلبية محددة والتأكد من أن qis يوافق total لنفس المادة (التي لها id معيّن) كما ذكرت في السؤال. أنصحك أيضاً في المستقبل بكتابة اسماء الحقول بلغة مفهومة أكثر من الاختصارات qis, q, iid, ... لتصبح (quantity, order_id, item_id,...) حتى نستطيع فهم معنى هذه الحقول ونتمكن من مساعدتك بشكل أفضل
  18. يمكنك استخدام التابع pull كالتالي: update( { _id: id }, { $pull: { 'address.localAddresses': { street: 'Ava Revenue-111' } } } ); حيث ستقوم بالبحث عن المستند من خلال الرقم المعرّف الفريد id، وتقوم بإزالة الحقل street والقيمة الموافقة له من المصفوفة localAddresses. والتي تم الوصول إليها عن طريق استخدام dot notation ( address.localAddresses) لأنه عند استخدام unset سيبقى الحقل street موجود كونه من أصل بنية المستند ضمن هذه المصفوفة الفرعية ولكن عندها سيتم وضع القيمة null بدلاً من القيمة "Ava Revenue-111"
  19. أعتقد أن الكود المرفق فيه بعض التعديلات عن السؤال، فلم ألاحظ وجود oid أو حتى المتغيّر q في PHP. ولكن في حال كان قصدك عن إضافة القيمة التراكمية للحقل total: عندما يتم إجراء update سيتم استبدال قيمة الحقل total السابق بالقيمة التي يتم تعديلها ضمن الاستعلام، ولذلك يتم إضافة آخر قيمة للمتغيّر total في السجل لديك. يمكنك إجراء increment للحقل total من خلال إضافة القيمة التي نرغب بإضافتها بشكل تراكمي على القيمة السابقة للحقل بتنفيذ الاستعلام التالي: "UPDATE table SET qis= '" . $qis . "', total= total + '" . $total . "' WHERE idd =$id" ^^^^^^^^^^^^^^^ وبذلك لن يتم تجاهل القيمة الموجودة مسبقاً في الحقل total بل سيتم جميع أي قيمة جديدة إلى القيمة الموجودة.
  20. المشكلة هي أن الاستعلام الأول يقوم بإلبحث عن المستندات التي لها الحقل message يحوي الخاصية from مع قيمة الشرط فقط، أي يجب ألا يحوي هذا المستند أي خصائص أخرى داخل message سوى from. أما في الاستعلام الثاني: يتم النظر فقط إلى قيمة 'message.from' ولا تتأثر النتيجة بأي حقول أخرى موجودة ضمن الغرض message أو أي حقول أخرى موجودة في المستند الرئيسي لذلك سيتم إعادة نتائج مختلفة عند تطبيق كل منهما وفي حال عدم وجود أي مستند يحوي فقط خاصية واحدة from ضمن الغرض message ستكون النتيجة فارغة في الاستعلام الأول
  21. بدءً من الإصدار 5.7.1 يجب إضافة القيمة التالية إلى المعامل الثاني عند إنشاء الاتصال: useUnifiedTopology: true فيصبح كود الاتصال لديك بالشكل التالي: MongoClient.connect(myURL, { useNewUrlParser: true }, (err, db) => { if (err) throw err; console.log('connected successfully to the database'); db.close(); }); فقد تظهر رسائل تحذيرية عند الاتصال حسب النسخة التي تقوم باستخدامها، لذلك يمكنك إضافة إحدى هذه القيم عند ظهور رسالة تحذيرية عن إحداها: { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false }
  22. يجب أن يتم إنشاء هذا المسار في حال لم يكن موجود في جذر المجلّد وليس ضمن أي مجلّد فرعي آخر. مع التأكد من وجود الصلاحيات اللازمة للمستخدم الذي يقوم بتنفيذ الأمر. أحياناً قد يتطلب الأمر الإشارة إلى مسار ملف config من خلال تنفيذ الأمر التالي: mongod -f c:\path\to\mongod.conf أو: mongod --config c:\path\to\mongod.conf مع استبدال path/to/mongod.conf بالمسار الكامل لمكان وجود الملف mongod.conf
  23. يمكن إجراء ذلك بعدة طرق، يختلف تطبيق كل طريقة حسب حجم البيانات والأداء الذي ترغب بالحصول عليه في تطبيقك فبعض الطرق قد تكون أسرع من غيرها، ولكن المبدأ هو بإلتحكم بخصائص الاستعلام التالية: count - limit - skip، مثال باستخدام skip و limit: find({},{fields to show},{ skip: 10, limit: 5 }, function(err, results) { ... }); حيث يمكنك تمرير قيم متغيرة لكل من skip وهي عدد السجلات التي سيتم إهمالها استعادة السجلات التي تبدأ بعد هذا الرقم، و limit وهو العدد الإجمالي للسجلات التي سيتم استعادتها. مثال آخر: var perPage = 10 , page = Math.max(0, req.params.page) mymodel.find() .limit(perPage) .skip(perPage * page) .exec(function(err, data) { mymodel.count().exec(function(err, count) { res.render('data', { mydata: data, page: page, pages: count / perPage }) }) }) وبهذه الطريقة ستتمكن من إرسال معلومات عن العدد الإجمالي للصفحات الموجودة وعدد السجلات في كل صفحة والتي تساعد في إظهار أرقام الصفحات في واجهة المستخدم
  24. بما أنه تم حل المشكلة على الويب، وظهور اللغة العربية بهذا الشكل فقط عند تحرير الملف فيعود ذلك لنوع الترميز المستخدم في محرر النصوص لديك، لذلك تأكد من أن يكون نوع الترميز UTF-8 في خيارات محرر النصوص الذي تقوم باستخدامه.
  25. بسبب وجود القيد unique على قيمة حقل البريد الالكتروني، تظهر الرسالة بسبب وجود أكثر من مستند له بريد الكتروني فارغ null. فبما أن الحقل مطلوب required وأيضاً فريد، لا يجوز تشابه قيمة هذا الحقل مع مستندات أخرى حتى لو كانت null. حسب التوثيق الرسمي، عند وجود حقل له الخاصية unique وعند عدم إضافة أي قيمة لهذا الحقل يتم حفظ قيمة index له وهي null. والباني الخاص بـ index لهذه المجموعة سيفشل ويعيد الخطأ الذي تمت إعادته في حالتك. لذلك يمكنك إضافة مايدعى بـ sparse index أو المفتاح المتناثر لتطبيق فلتر على القيم الفارغة null، وعدم التسبب في ظهور هذا الخطأ. تطبيق المفتاح index على هذه الحقول وإعطائه القيمة unique يكون بالشكل التالي: users.createIndex( { "info.email": 1 }, { unique: true } ) أما لتطبيق خاصية sparse index فهي بالشكل التالي: users.createIndex( { "info.email": 1 }, { sparse: true } ) وعندها يستطيع sparse index التعامل مع عدة قيم null ولن يحصل الخطأ السابق.
×
×
  • أضف...