<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Mohammad Jawad Barati</title><link>https://virgool.ir/feed/@node.js.developers.kh</link><description>برنانه نویس، مدرس، محقق. عاشق انیمه هستم  و دنبال چالش ها جدید.</description><language>fa</language><pubDate>2026-11-11 18:47:32</pubDate><image><url>https://files.virgool.ir/upload/users/239939/avatar/Db99kX.png</url><title>Mohammad Jawad Barati</title><link>https://virgool.ir/@node.js.developers.kh</link></image><item><title>آخرین پست های فنی من در ویرگول</title><link>https://virgool.ir/@node.js.developers.kh/آخرین-پست-من-در-ویرگول-اشغال-kqms4t0oa8yc</link><description>به علت از دست دادن پست هایی که بارها در ویرگول مینوشتم و بعد از چندین ویرایش ناقص میشدند تصمیم گرفتم که دیگر در ویرگول که باعث می شود دیتا هایم را که با زحمت برای شما می نوشتم را در لینکدین یا به احتمال خیلی کم در امیگو (البته در مورد این هنوز به اطمینان دست نیافتم) بزارم.اگر هم سایت/وبلاگ خودمو راه انداختم اینجا میزارمش. فعلا اینجا ها هستم: من توی discord ببینید: https://discord.gg/3tCEycytمن توی reddit ببینید:‌ https://www.reddit.com/user/m-jawad-b-khorasaniمن توی لینکدین: https://www.linkedin.com/in/kasir-barati-450b141b3از تلگرام دارم میرم روی discord</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sun, 07 Nov 2021 14:49:53 +0330</pubDate></item><item><title>دوره NestJS شروع شد. اموزش فریمورک NestJS توسط کثیر براتی</title><link>https://virgool.ir/@node.js.developers.kh/دوره-nestjs-شروع-شد-اموزش-فریمورک-nestjs-توسط-کثیر-براتی-jpc2rvhoubym</link><description>سلامخیلی خوشهال و ذوق زده هستم. اولین دوره اموزشی خودم رو دارم رکورد میکنم و امیدوارم با پشتیبانی شما و نظارتتون بر کیفیت و تعهد من به دوره یه دوره اموزشی قوی رو تولید بکنیم. برای donation و پشتیبانی هم میخوام یه Smart Contract بنویسم تا توی اون کارامون رو جلو ببریم.فقط یه موضوعی، حتما share کنید تا تعداد افرادی که میبینن بیشتر بشه. چونکه در این صورت تعداد نظرات هم بیشتر میشه و من با توجه به یه جامعه مخاطب بیشتر میتونم یه دوره بهتر ارائه بدم. پیشنهادی هم برای ارتقاء کیفیت دوره (چه از نظر محتوا، چه از نظر ظاهر) داشتید بهم بگید.جلسه اول https://www.aparat.com/v/PjeQw/ تو این جلسه در مورد تاپیک ها صحبت کردم.جلسه دوم https://www.aparat.com/v/GJPOK تو این جلسه هم گفتم که NestJS چیه و چرا باید ازش استفاده کرد.جلسه سوم https://www.aparat.com/v/gLYx4 تو این جلسه سعی کردم که در مورد انچه که در آینده قرار هست ببینیم گفتم.جلسه چهارم https://www.aparat.com/v/fG4vj تو این جلسه روی این موضوع که چجوری یه اپلیکیشن NestJS ای با CLI خود NestJS بسازید و اینکه از چه بخش هایی تشکیل شده رو بهتون گفتم. در مورد نحوه اجرا شدن اپلیکیشن های NestJS ای بهتون یه سر نخ هایی دادم. فایل هایی که خود NestJS تولید میکنه رو گفتم چیه و منتظر جلسه بعدی باشید که تازه من دارم داغ میام و میخوام همه چی رو بهتون یاد بدم.جلسه پنجم https://www.aparat.com/v/Z4V7h جلسه ششم https://www.aparat.com/v/Td3P8 جلسه هفتم https://www.aparat.com/v/DKkCO </description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sat, 24 Jul 2021 12:58:56 +0430</pubDate></item><item><title>کار با tabnine و داستان student discount اش</title><link>https://virgool.ir/@node.js.developers.kh/کار-با-tabnine-و-داستان-student-discount-اش-rq8dccc5k7sj</link><description>یه ۳ ماهی میشه دیگه دارم از tabnine استفاده میکنم. واقعا ورژن free اون هم کار راه اندازه. فوق العاده قوی و خوبه و سرعت توسعه رو فوق العاده بیشتر میکنه. همونجوری که میدونید از AI استفاده میکنه تا code suggest بکنه. بعضیا میگن سنگینه و ...، والا من که کلا تغییری حس نکردم.همین چند وقت پیشا یه ایمیل برام زده بود و توش از رایگان شدن tabnine pro برای student ها گفته بود. والا من که خیلی وقته دانشجو نیستم (و کلا دانشگاهمون هم بهمون ایمیل دانشجویی نداد). ولی اونایی که ایمیل دانشجویی دارن حتما برن و استفاده بکنن.نکته ای که منو وادار کرد این پست رو بنویسم این بود که تو سرور discord شون یه سوال پرسیدم که منظورم این بود که برای ادمایی که دانشجو هستن ولی ایمیل دانشجویی ندارن چی، گفت خب به ما یه ایمیل بزنید و شواهدی مبنی بر اینکه دانشجو هستید ارائه بدید تا براتون tabnine pro رو فعال کنیم.واقعا شاید بشه گفت خیلی جالبه. ساپورت و پشتیبانی تا این حد.خوش خرم باشید.راستی من جدیدا کمتر تو ویرگول مینویسم که ۲ تا دلیل داره:دارم یه دوره NestJS تهیه میکنم که تو اپارات و youtube اپلود میکنمشون. البته اینجا هم پستش رو درست میکنم (به دوستانتون لینک های ارتباطی با من رو بدید تا از دست ندن چیزی رو)تو لینکدین خودم مطلب مینویسم (فارسی نیست، انگلیسی هست).کانال های ارتباطی با من:تلگرام: nodejsdeveloperskhاینستاگرام: node.js.developers.khلینکدینایمیل: node.js.developers.kh@gmail.com</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Thu, 22 Jul 2021 15:51:14 +0430</pubDate></item><item><title>سری اموزش های grafana برای خودم</title><link>https://virgool.ir/@node.js.developers.kh/سری-اموزش-های-grafana-برای-خودم-yw899hjfdole</link><description>گرافانا یه ابزار برای مانتورینگ هست که با گو لنگ نوشته شده و سرعت خوبی داره. ریسورس مناسبی نیاز داره. چرا ما به مانیتورینگ نیاز داریم؟ چونکه میخوایم مطمئن بشیم که اپلیکیشن و سرورمون در چه وضعیتی به سر میبرن و پرفرومنسی که مد نظر ما هست رو دارن؟ اگه به مشکلی خورد به کی خبر بده و از چه طریقی؟ اگه سیستم پایین رفت ادمین میتونه خیلی سریع بیاد بررسی کنه.توی DevOps ما مبحثی داریم تحت عنوان DevOps Lifecycle که یکی از اونا بخش Continuous monitoring هست که در ادامه بهش می پردازم.معنی Continuous monitoring اینه که ما یه سیستمی داشته باشیم که بتونیم توسط اون مشکلات امنیتی و باگ های سیستم رو تشخیص بدیم و این سیستم هم به صورت اتوماتیک کار کنه و توی تک تک این lifecycle ای که DevOps داره وجود داشته باشه.برای این Continuous monitoring ما یسری ابزار داریم، که اینجا اونایی که فقط خودم باهاشون کار میکنم رو میارم:برای مانیتورینگ prometheus داریم.برای metric storage از Influxdb استفاده می کنیم.برای visualization ابزار Grafana رو داریم.گرافانا چیه؟یه وب اپلیکیشن کاملا اپن سورس multi-platform برای انالیز و visualize کردن دیتا که بهت چارت، گراف و alert میده. توی گرافانا میتونی dashboard های خودت رو بسازی و ...نکات خوب grafana:از دیتابیس های زیادی پشتیبانی میکنه و تو میتونی همشون رو تو یه داشبورد با هم داشته باشی. هر جایی هست (ویندوز، لینوکس، داکر، مک)یه مشته library براش وجود داره که خیلی کارت رو ساده میکنهمیتونی تیم بسازی توش و به هر کدوم از اعضای تیمت دسترسی بدی تا به داشبورد ها دسترسی داشته باشن.توی گرافانا میتونیم داشبورد هامون رو export و import بکنیم.دیپلوی کردن Grafana روی داکرخیلی ساده هست. همش توی این ریپو هست.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Tue, 22 Jun 2021 19:37:41 +0430</pubDate></item><item><title>مقایسه EFK با PGL</title><link>https://virgool.ir/@node.js.developers.kh/مقایسه-efk-با-pgl-wih9rzrydwfm</link><description>من این جا قصد ندارم چیزی رو تایید یا رد کنم. فقط جهت رضای خودم و داکیومنت کردن نوشتمش. پس خواهشا به چشم یه مقاله علمی بهش نگاه نکنید.استک EFKواقعا ریسورس خور هستن. مخصوصا اگه به این stack بیای logstash رو هم اضافه کنی. طبیعی هم هست دیگه (این stack با جاوا نوشته شدن و elasticsearch یه دیتابیس NoSQL ای هست)برای ingest ،visualize و query زدن روی لاگ هامون استفاده میکنیمدیتا تو Elasticsearch روی دیسک به صورت ابجکت های unstructured ذخیره میشههم key هم value ایندکس میشه (فکر کنم ذات Elasticsearch اینه، full text search منظورمه)توی اینجا data collector مون filebeat هست که اگه stack مون FELK بود data collector مون Logstash میشد و دستمون خیلی بازتر بود. یعنی شما میتونی از چند تا source ورودی بگیری.از اونجایی که ما اینجا یه دیتابیس (Elasticsearch) داریم، Kibana ابزار های قدرتمندی برای انالیز دیتا، machine learning، گراف برای نمایش دادن ارتباط داده ها به هم، location map ها توی Kibana میتونیم alert ست کنیم تا تحت یه شرایط خاص بهمون نوتیفیکیشن ارسال کنه.توی این استک ما برای Kibana به یه دیتابیس نیاز نداریم تا دیتا هاشو توش بریزیم. دیتاهاش توی Elasticsearch ذخیره میشن.استک PGLریسورس کمتری میخواد. (با گو لنگ نوشته شدن)لوکی single-binary mode هست و دیتا ها رو روی دیسک ذخیره میکنه.دیتا به horizontally-scalable mode توی کلود استوریج هایی مثل S3 ،GCS یا Cassandra ذخیره میشه.لاگ ها plaintext ذخیره میشن و label میخورن.فقط label ها ایندکس میشن و این یه tradeoff هست (به جای full index داره فقط label ها رو ایندکس میکنه) که باعث میشه دولوپر هر چقدر دلش میخواد لاگ تولید کنه (نظر شخصی اینجانب نیست. رفرنس).ابزار Promtail فقط برای کار با Loki ساخته شده، یعنی discover میکنه لاگ فایل ها روی دیسک رو و بهشون label میزنه و بعدش میده به Loki.وقتی روی k8s باشی service discovery برای pod هایی که روی یه node اجرا میشن داریم. توی محیط داکر Promtail به عنوان یه sidecar کانتینر هست که لاگ ها رو از محلی که براش مشخص کردیم میخونه روشی که Loki لاگ ها رو نشون میده شبیه به روشی هست که Prometheus داره metric ها رو نشون میده. یعنی label های مشابه دارن، این بهت کمک میکنه که خیلی راحت بین لاگ های سیستمت و metric های سرور جابجا شیتوی این استک ما علاوه بر prometheus به influxdb هم نیاز داریم.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Tue, 22 Jun 2021 17:05:50 +0430</pubDate></item><item><title>کانفیگ کردن ELK و EFK روی داکر</title><link>https://virgool.ir/@node.js.developers.kh/کانفیگ-کردن-elk-روی-داکر-tt7soxubiyug</link><description>دنبال یه سولوشنی هستی که لاگ گیری رو به صورت self-hosted هندل کنی؟ میخوای لاگ های کانتینر هاتو با ELK به صورت centralized داشته باشی؟ کاری که من سردردشو دارم؟ جای درستی اومدی.مقدماتاین ریپو رو کلون کن. حالا یه `ss -ntl` بزن و مطمئن شد که پورت های زیر ازاد هستنبرو توی تنظیمات کرنل و مقدار vm_max_map_count رو زیاد کن (حداقل ۲۶۲۱۴۴ باشه).sudu su root; &#xA;echo 262144 &gt; /proc/sys/vm/max_map_countیا مستقیم بزن sudo sysctl -w vm.max_map_count=262144;حالا وقت ران کردن ELK مون هست. پس توی اون ریپویی که کلون کردی ترمینال رو باز کن و دستور `docker compose up` رو بزن (ممکنه برای تو هم مثل مال من docker compose کار نکنه، یه باگی بوده که فیکس شده ولی تا توی پروژه اصلی بیاد زمان بره)docker-compose upچند تا مسئله:نام کاربری Elasticsearch اینه: elastic و پسوردش هم changeme هست.اگه کانتینر های kibana و Logstash برای تو هم مثل مال من exit شدن و ارور داشت به ریپوی خودم توی گیت هاب یه سر بزن و اون کلون کنقسمت ساده تموم شد. حالا میرسیم سر بخش های سختحالا فرض کن یه اپ نود.جی‌اسی داری که لاگ هاشو میخوای ship کنی توی ELK خودت و ۳ تا option داری:کانفیگ کردن filebeat: توی filebeat ما یسری فایل مشخص رو به عنوان سورس در نظر میگیریم. میتونی لاگ ها رو از filebeat بدی به logstash یا مستقیم بدی دست خود elastic (هر چند ما این کارو نمیکنیم، چونکه توی logstash ازادی عمل بیشتری داریم و به راحتی میتونیم بگیم لاگ ها با چه فرمتی به elastic برن). رفرنس، رفرنس کانفیگ های Elasticsearchکانفیگ کردن EFKدنبال یه سولوشنی دیگه هستی که ریسورس کمتری نسبت به ELK بخوره. چطوره به جای Logstash از Filebeat استفاده کنی؟ چرا ریسورس زیادی میخوره logstash؟ چونکه JVM میخواد. پس بریم سراغ مراحل:همونطوری که میبینی داکر به صورت پیشفرض لاگ هاشو با درایور پیشفرضش توی فایل ذخیره میکنه. filebeat هم که یسری فایل بهش میدی و اونم اون فایل ها رو به elasticsearch میده. پس فقط کافیه filebeat رو بگی باید از کجا فایل ها رو برداره.برای اینکه این EFK رو بیاری بالا یه docker compose فایل لازم داری:version: &#34;3.7&#34;services:  elasticsearch:    image: &#34;docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}&#34;    environment:      - &#34;ES_JAVA_OPTS=-Xms1g -Xmx1g&#34;      - &#34;discovery.type=single-node&#34;    ports:      - &#34;9200:9200&#34;      - &#34;9300:9300&#34;    volumes:      - elasticsearch_data:/usr/share/elasticsearch/data  kibana:    image: &#34;docker.elastic.co/kibana/kibana:${ELK_VERSION}&#34;    ports:      - &#34;5601:5601&#34;  filebeat:    image: &#34;docker.elastic.co/beats/filebeat:${ELK_VERSION}&#34;    user: root    volumes:      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro      - /var/lib/docker:/var/lib/docker:ro      - /var/run/docker.sock:/var/run/docker.sockvolumes:  elasticsearch_data:همونطوری که متوجه شدی این filebeat رو باس یجوری کانفیگ کنی: پس ما یه yaml فایل دیگه هم میخوایم تا کانفیگ های filebeat رو توش بنویسیم، پس یه volume رو به صورت Readonly به کانتینر میدیم.- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:roحالا وارد بخش بعدی میشیم: filebeat برای اینکه لاگ های داکر رو به elasticsearch بده باید به لاگ های داکر دسترسی داشته باشه، لاگ های کانتینر های داکری معمولا توی مسیر زیر هستن. فکر کنم حالا حکمت دومین volume رو بیشتر فهمیده باشید./var/lib/docker/containersولی خب پس چرا socket داکر رو با کانتینر به اشتراک گذاشتیم؟ چونکه filebeat ممکنه به اسم ایمیج یا اسم کانتینر نیاز داشته باشه و اینا چیزایی نیستن که توی log فایل ها باشن. در ضمن ما برای kibana نیازی به volume نداریم، چونکه تنظیماتش رو elasticsearch برامون persist میکنه. ولی خود elasticsearch نیاز به volume داره. حالا بیایید filebeat رو کانفیگ کنیم:filebeat.inputs:&#xA;  - type: container&#xA;    paths:&#xA;      - &#34;/var/lib/docker/containers/*/*.log&#34;&#xA;&#xA;processors:&#xA;  - add_docker_metadata:&#xA;      host: &#34;unix:///var/run/docker.sock&#34;&#xA;&#xA;  - decode_json_fields:&#xA;      fields: [&#34;message&#34;]&#xA;      target: &#34;json&#34;&#xA;      overwrite_keys: true&#xA;&#xA;output.elasticsearch:&#xA;  hosts: [&#34;elasticsearch:9200&#34;]&#xA;  indices:&#xA;    - index: &#34;filebeat-%{[agent.version]}-%{+yyyy.MM.dd}&#34;&#xA;&#xA;logging.json: true&#xA;logging.metrics.enabled: falseکلش رو هم میتونی از این ریپو کلون کنی. نکته مهم اینه که یوزر پیشفرض ایمیج filebeat نمیتونه به این فایل دسترسی داشته باشه و ما مجبوریم chown این فایل رو به root تغییر بدیم و اگه تغییر ندی همچین اروری میگیری که اینجا در موردش توضیح دادهExiting: error loading config file: config file (&#34;filebeat.yml&#34;) must be owned by the user identifier (uid=0) or rootالبته ممکنه بعد از کامند `sudo chown root filebeat.yml` کارت حل نشه. پس بهتره که کامند زیر رو بزنی:sudo chmod go-w filebeat.ymlمرحله بعدی اضافه کردن یه index pattern هست:وب بعدش:در نهایت هم اینو داریحال کردی بکوب لایک رورفرنس</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Tue, 15 Jun 2021 18:32:08 +0430</pubDate></item><item><title>دیزاین پیترن های microservice</title><link>https://virgool.ir/@node.js.developers.kh/دیزاین-پیترن-های-microservice-iisl4arikjbc</link><description>میکروسرویس ها این روزا خیلی ترند شدن و دیگه هر جایی میری ازت میخوان میکروسرویس کار کنی ولی باید یادت باشه که میکروسرویس مشکلاتی رو حل میکنه ولی مشکلاتی هم خلق میکنه. پس design pattern هایی لازم داریم تا مشکلات رو حل کنیم.معرفی principle های میکروسرویسراحت باشه scale کردنش (Scalability)باعث بشه سرویس هات بیشتر در دسترس باشن (Availability)سرویس هات flexibility بیشتری داشته باشن (Resiliency)سرویس های Independent و autonomous داشته باشیمرکزیت نداشته باشی (Decentralized governance)هر سرویس از بقیه سرویس هات ایزوله باشه (Failure isolation)Auto-Provisioningداشتن Continuous deliveryتوی میکروسرویس تلاشمون روی loosely coupled کردن سرویس هاست تا هر سیستم فقط یه وظیفه داشته باشه.Decomposition PatternsDecompose by Business CapabilityDecompose by SubdomainStrangler PatternIntegration PatternsAPI Gateway PatternAggregator PatternClient-Side UI Composition PatternDatabase PatternsDatabase per ServiceShared Database per ServiceCommand Query Responsibility Segregation (CQRS)Saga PatternObservability PatternsLog AggregationPerformance MetricsDistributed TracingHealth CheckCross-Cutting Concern PatternsExternal ConfigurationService Discovery PatternCircuit Breaker PatternBlue-Green Deployment Patternرفرنس</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Mon, 14 Jun 2021 14:53:03 +0430</pubDate></item><item><title>تابع aggregate و operator هاش تو مانگو دی بی</title><link>https://virgool.ir/@node.js.developers.kh/تابع-aggregate-و-operator-هاش-تو-مانگو-دی-بی-llib0rzseifk</link><description>عملگرهای مورد استفاده تو توابع aggregate، داکیومنت ها رو پردازش کرده و نتیجه محاسبه شده رو بر میگردونن.مقدمهکالکشن point-types{ amount: number; title: string; type: string }کالکشن point{ amount: number; basedOn: string; contractor: string; projectId: string; type: string }توی کالکشن بالا contractor کلید خارجی به کالکشن contractors هست.توی کالکشن بالا projectId کلید خارجی به کالکشن demand-lead هست.توی کالکشن بالا type کلید خارجی به کالکشن point-types هست.عملگر lookupاین عملگر برای left outer join استفاده میشه. برای equality match هست. فرض کن میخوای شرطی بزاری که نیاز داره چند تا کالکشن رو با هم join بزنی. مثلا تو میخوای روی کالکشن point کوئری بزنی و بگی point هایی رو بهم بده که کلید type شون به point-types ای اشاره داره که type اون برابر با مقدار X هست.جوین کردن دیتا از یه input collection (کالکشنی که روش کوئری رو اجرا میکنی) و یه lookup collection (کالکشنی که دیتا توشه).ما همچین کوئری ای میزنیم:{&#xA;  from: &#39;point-types&#39;,&#xA;  localField: &#39;type&#39;,&#xA;  foreignField: &#39;_id&#39;,&#xA;  as: &#39;pointType&#39;&#xA;}حالا توی اون فیلد جدید (pointType) تو type رو داری (مطالعه بیشتر). حالا میخوای اون شرط رو بزنی:         {&#xA;            $match: {&#xA;                contractor: ObjectId(&#39;id&#39;),&#xA;            },&#xA;        },&#xA;        {&#xA;            $lookup: {&#xA;                from: &#39;point-types&#39;,&#xA;                localField: &#39;type&#39;,&#xA;                foreignField: &#39;_id&#39;,&#xA;                as: &#39;pointType&#39;,&#xA;            },&#xA;        },&#xA;        {&#xA;            $unwind: {&#xA;                path: &#39;$pointType&#39;,&#xA;            },&#xA;        },&#xA;        {&#xA;            $match: {&#xA;                $expr: {&#xA;                    $eq: [&#39;$pointType.type&#39;, &#39;bad-status-set-out&#39;],&#xA;                },&#xA;            },&#xA;        },این کوئری فقط اونایی رو بر میگرودونه که type شون برابر با رشته X باشه.رفرنس</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sun, 02 May 2021 13:37:19 +0430</pubDate></item><item><title>ساختن یه سیستم matchmaking توی نود.جی‌اس</title><link>https://virgool.ir/@node.js.developers.kh/ساختن-یه-سیستم-matchmaking-توی-نودجی-اس-qic4jgbfv6w8</link><description>مفهوم match making چیه؟ بیاید فرض کنیم شما وب سایت پونیشا رو راه انداختید. حالا میخواید به کسایی که ثبت سفارش پروژه میکنن پیشنهاد بدی که از بین این برنامه نویسایی که برای اجرا کردن پروژه ی تو درخواست فرستادن کدوم خوب تر هست. یعنی بیای بر اساس یه سری پارامتر به کسی که پروژه رو ثبت کرده بگی بر اساس مثلا خوش قولی و کیفیت کار فلان برنامه نویس امتیاز ۹۰ گرفته و فلانی امتیاز ۶۷ و ...البته اصل این مفهوم رو من تا الان بیشتر توی game و business دیدم. مثالش میتونه یه چیزی مثل پکیج matchmaker و tiny-matchmaking. یا این ریپوزیتوری گیت هاب باشه.پس در کل میشه گفت matchmaking میاد بر اساس پارامتر هایی مگه دو تا چیز چقدر با هم برابر هستن. چیزی که مشخصه اینه که امتیاز هر فرد توی اون پارامتر ها از قبل مشخص شده است. البته ممکنه که امتیاز number نباشه و boolean باشه.برای این تعیین امتیاز هم الگوریتم داریم یا اینکه فرد مستقیم میاد اونو وارد میکنه. بعد از هر بار وارد شدن مقدار جدید باید مجموع/میانگین امتیاز فرد توی اون پارامتر دوباره حساب بشه. اگه قرار باشه میانگین حساب بشه باید مقادیر قبلی اون پارامتر رو داشته باشید تا بتونید میانگین بگیرید.چیزی هم که ممکنه اتفاق بیفته اینه که شما بگی من یه حداقلی برای سیستمم تعیین میکنم، یعنی اگه کاربری امتیازش کمتر از اون شد اصلا توی نتیجه نهایی نشونش نمیدم. این ممکنه برات این مشکل رو بوجود بیاره که اصلا هیچ کاربری قبول نشه. پس بای به فکر بود که توی این شرایط چکار کرد.تعریف چند تا واژهلغت skill system: یه معیار که بهت میگه کاربرت چقدر خوبه لغت ranking system: سیستمی که به کاربرات میگه چقدر خوب یا بد هستن. این سیستم ممکنه از skill system استفاده بکنه یا نکنه.لغت matchmaking system: سیستمی که کاربرا رو با هم match میکنه. ممکنه از skill system استفاده بکنه، ممکنه از ranking system استفاده بکنه ولی چیزی که مشخصه اینه که matchmaking system روی دو تا سیستم دیگه تاثیر میزاره. https://www.dideo.ir/v/yt/-pglxege-gU/skill%2C-matchmaking%2C-and-ranking-systems-design چند دقیقه اول این فیلم رو ببینید.خب قبل از هر چیزی بیاید مرحله به مرحله کار رو پیش ببریم. اول یه کالکشن ایجاد بکنیم تا روش بتونیم تست هامون رو اجرا کنیم. یه فایل به اسم point.schema.js ایجاد کنید :// @ts-check&#xA;const { Schema } = require(&#39;mongoose&#39;);&#xA;const pointSchema = new Schema({&#xA;    type: {&#xA;        type: String,&#xA;        enum: [&#39;Point&#39;],&#xA;        default: &#39;Point&#39;,&#xA;    },&#xA;    coordinates: {&#xA;        type: [Number],&#xA;        required: true,&#xA;    },&#xA;});&#xA;module.exports = { pointSchema };ما type های مختلفی توی GeoJSON میتونیم داشته باشیم؛ Point که اشاره به یه نقطه روی نقشه داره، Polygon که یه محدوده رو در بر میگیره، LineString که توضیح دادنش با مثال ساده تره: فرض کن میخوای track جاهایی رو که رفتی نگهداری، در این صورت میتونی از این نوع استفاده بکنی. نوع های MultiPoint و MultiPolygon و MultiLineString هم داریم که چند تا نقطه یا polygon یا LineString رو نگه میدارن.و یه فایل test.schema.js// @ts-check&#xA;const { Schema, model } = require(&#39;mongoose&#39;);&#xA;const { pointSchema } = require(&#39;./point.schema&#39;);&#xA;const COLLECTION_NAME = &#39;test&#39;;&#xA;const schemaName = new Schema(&#xA;    {&#xA;        location: {&#xA;            type: pointSchema,&#xA;            index: &#39;2dsphere&#39;,&#xA;        },&#xA;    },&#xA;    {&#xA;        timestamps: true,&#xA;        collection: COLLECTION_NAME,&#xA;    },&#xA;);&#xA;&#xA;const SchemaModel = model(COLLECTION_NAME, schemaName);کاری که میخوایم بکنیم اینه که روی location یه matchmaking درست کنیم. خب مثل همیشه بیاید اول با کلیت آشنا بشیم. برای اینکه بتونید کوئری زیر رو اجرا بکنید باید اول روی فیلد GeoJSON خودتون index گذاری بکنید. به همین خاطر ما فیلد location رو index گذاری کردیم.چند نوع ایندکس گذاری داریم: نوع 2d: ایندکس گذاری قدیمی برای زمانی که داری فیلدت رو توی آبجکت های GeoJSON ذخیره نمیکنی هست.نوع 2dsphere که نوع جدید ایندکس گذاری هست و توی اکثر موارد استفاده میشه چونکه حتی از روش قدیمی ذخیره دیتا پشتیبانی میکنه.روش قدیمی ذخیره لوکیشن.نوع geoHaystack که use case خاص خودش رو داره و من اصلا نمیدونم چیه. پس کلا بهتره شما هم فعلا بیخیالش بشید.برای جزئیات بیشتر این ویدئو رو ببینید: https://aparat.com/v/TSBMy حالا بیاید سراغ کوئری بریم:  const result = await SchemaModel.find({&#xA;        location: {&#xA;            $near: {&#xA;                $maxDistance: 100000,&#xA;                $geometry: {&#xA;                    type: &#39;Point&#39;,&#xA;                    coordinates: [36.3, 59.41],&#xA;                },&#xA;            },&#xA;        },&#xA;    });اگرم چیزی به عنوان خروجی برگشت داده نشد اون عددای coordinates و maxDistance رو عوض کنید. این کوئری رکورد هایی رو بر میگردونه که near (نزدیک) geometry داده شده هستن.حالا این maxDistance چی هست؟ تعیین کننده حداکثر فاصله ای هست که به عنوان near حساب میکنهواحدش متر هست میخوای بیشتر در مورد operator های MongoDB بدونی؟نکته مهم: You cannot combine the $near operator, which requires a special geospatial index, with a query operator or command that requires another special index. For example you cannot combine $near with the $text query.مثلا اگه میخوای or بزنی و بگی چند تا عملگر near داشته باشی باید چند تا کوئری مجزا بزنی و نتیجه رو با هم ترکیب بکنی. نکته بعدی اینه که near باید توی root کوئری باشه و نمیتونی اونو بزاری توی level های پایین تر. همون طوری که توی این لینک توضیح داده شده. رفرنس هر دو تا نکته ی بالایی.خب ولی کاری که من اینجا میخوام بکنم اینه که یه کاربر داریم که ما ۴ تا لوکیشن مختلف ازش داریم: محل کارگاهش محل زندگیشمحل نمایشگاهشو محل دفترشحالا میخوایم بگیم که کدوم کاربرا، یکی از این لوکیشن هاشون به یه نقطه خاص، نزدیک هست. اون کاربرا باید اطلاعاتشون برگشت داده بشه. پس با operator (عملگر) near مشکل حل نمیشه، یا اینکه باید ۴ تا کوئری بزنیم. پس میریم سراغ عملگر geoWithin.عملگر geoWithinاز این عملگر توی aggregate ها استفاده میکنیم. این عملگر داکیومنت هایی رو بر میگردونه که location اونها توی یه محدوده خاص هست. حالا این محدوده رو میتونی با polygon یا ... تعیین بکنی. ما عملگر های shape مختلفی توی MongoDB داریم:عملگر boxعملگر polygonعملگر centerعملگر centerSphereاین دو تا عملگر آخری برامون یه دایره میکشن. عملگری که در ادامه مخیوام توضیح بدم عملگر centerSphere هست. این عملگر یه آرایه میگیره. این آرایه دوتا عضو بیشتر قبول نمیکنه. ایندکس صفر باید coordinates مرکز دایره باشه و ایندکس دوم باید مشخص کننده شعاع دایره باشه.این شعاع به مایل هست مثلا ۱۰ مایل. البته نکته ای که هست اینه که باید این ۱۰ مایل رو تقسیم بر شعاع استوایی زمین بکنید. شعاع استوایی زمین به مایل 3963.2 هست. پس در نهایت یه همچین چیزی داریم:همون طوری که میبینید توی کوئری بالا گفتم تا شعاع یک کیلومتر بگرده و هر کی خونش یا دفتر کارش توی دایره ای که مرکز اون coordinates ای که دادم هست رو برام برگردونه.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Mon, 26 Apr 2021 18:57:30 +0430</pubDate></item><item><title>اپلیکیشن هایی که یه دولوپر روی لینوکس نصب میکنه</title><link>https://virgool.ir/@node.js.developers.kh/اپلیکیشن-هایی-که-یه-دولوپر-روی-لینوکس-نصب-میکنه-erhj5nsnrwa8</link><description>میخوام توی این پست در مورد یه سری اپلیکیشن که خیلی نصب میشن صحبت بکنم.سیستم عامل لینوکساولیشون سیستم عامله که من اوبونتو/مانجارو نصب میکنم. پیشنهاد من اینه که نسخه LTS نصب بکنید. برای نصبش هم میتونید به این پست توی مکتب خونه یه نگاه بندازیداپلیکیشن flameshotکه یه اپلیکیشن خیلی خوب و کاربردی برای screenshot گرفتن هست.اینم از دستوری که برای نصبش باید بزنید:apt install flameshotاپلیکیشن Postman من آخرین نسخه رو از سایت خود Postman دان میکنم و بعدش به کمک این tut میام نصب و کانفیگش میکنم.داکربرای نصب داکر به نظر من هیچی بهتر از داک خودش نیست. پس بیاید یه نگاهی به داک داکر بندازیم تا بدونیم چجوری نصب و کانفیگش باید بکنیم.ایمیج bitnami/redis ایمیج nodeایمیج bitnami/mongodbایمیج mongo-expressایمیج wordpressایمیج mysqlایمیج postgresالبته همیشه یه تگ مشخص رو pull کنید. چونکه بعدا به مشکل میخورید اگه از latest استفاده بکنید.گوگل کرومبرای نصب گوگل کروم کافیه برید تو سایتشون و فایل .deb شون رو دان کنید. بعدش هم که کافیه با استفاده از  دستور `dpkg -i` اونو نصب بکنید.نصب اکستنشن Ultrasurf یا Zenmate برای دور زدن تحریم ها و فیلتر هانصب اکستنشن Grammaly برای املا و گرامر و ...نصب اکستنشن wappalyzer برای اینکه بفهمی یه سایت رو با چه تکنولوژی هایی ساختن.نصب اکستنشن metamask برای cryptocurrency اکستنشن Link to Text Fragment برای وقتی که میخوام به یه متنی تو یه سایت لینک بدم.اکستنشن JSON Viewer برای نمایش دادن قشنگ تر json توی مرورگراکستنشن Marinara: Pomodoro برای time management و focus کردن روی کارااکستنشن gofullpage برای اسکرین شات گرفتن از یه صفحه‌ی یه سایتاکستنشن Google Dictionary فوق العاده قوی و خوب برای معنی واژه ها (انگلیسی به انگلیسی). حتی توی popup خوش هم میتونی double click کنی تا معنی اون لغت رو هم نشون بده.اکستنشن fake-filler برای پر کردن فرم با مقادیر fakeاکستنشن remiders برای یاد اوری کار هامون.اپلیکیشن uGetبرای نصب این اپلیکیشن فقط باید `apt install uget` رو توی ترمینال با دسترسی root اجرا بکنی.اپلیکیشن vlc برای نصب این player معروف کافیه توی ترمینال `sudo apt install vlc` بزنی.اپلیکیشن GIMPبرای نصب این نرم افزار ویرایش تصویر هم `sudo apt install gimp` کافیهنود.جی‌اسبرای نصب میتونید به این صفحه گیت هاب مراجعه بکنید و مطابق distro لینوکسی که استفاده میکنید عمل بکنید. پیشنهاد من نصب نسخه LTS هست.اپلیکیشن Kazamیه اپلیکیشن برای record کردن صفحه نمایش دستگاه خودتون. نصب با اجرای کامند `sudo apt install kazam`اپلیکیشن cherrytreeیه اپلیکیشن خوب برای نوت برداریاپلیکیشن vscodeیه IDE خوب برای کد زدن. برای نصبش دانلود و بعدش با کامند dpkg نصبش کنید. اکستنشن های زیر اینه:نصب prettierنصب TODO: ابزاری که بهت اجازه میده کامنت های با معنا تری توی محیط development بنویسی.نصب MongoDB ID Generator برای تولید کردن ObjectIdنصب GitLens برای کار کردن با گیتنصب CodeSnap برای اسکرین شات گرفتن از کد هاتنصب Bracket Pair Colorizerنصب Quokka.js یه playground خیلی باحال برای جاوااسکریپت.نصب Project Manager برای اینکه از دست file explorer و سرچ کردن برای پروژه هات خلاص بشینصب Vuln Cost - Security Scanner نمایش دادن اخطار برای پکیج های 3rd party مشکل دار.نصب اکستنشن Tabnine Autocomplete AI برای بهتر کد زدن و productivity بیشتر. فوق العاده قدرتمنده و از AI برای Intellisense دادن استفاده میکنه.اکستنشن code spell checkerرفرنساپلیکیشن MongoDB Compassنصبش هم خیلی راحته. یه `apt update; apt upgrade` بعدش پکیج .deb اش رو از سایتش دان کن و با dpkg نصب.اپلیکیشن psensorیه اپلیکیشن خوب برای چک کردن دمای سی پی یو و .... برای نصبش هم به این پست یه نگاهی بندازید یا این دستورات رو توی ترمینال بزنید:sudo apt install lm-sensors&#xA;sudo apt install psensorحالا برنامه psensor رو اجرا بکن.ترمینال - tmuxیه ابزار برای تقسیم کردن ترمینال به چندین بخش. نصب با `sudo apt install tmux`نصب کردن چیزهای دیگهتوی این لینک برید و پکیج ubuntu-restricted-extras رو نصب بکنید.اپلیکیشن Zeal با تشکر از آقای Sina Jamzad که توی کامنت ها جواب دادن به درخواست ما. این اپلیکیشن هم برای کسایی که آفلاین هستن یا دوست دارن داکیومنت ها رو به صورت آفلان هم داشته باشن خوبه. برای نصبش این سایت خودشونه. توی اوبونتو هم `sudo apt install zeal`</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sun, 25 Apr 2021 11:23:47 +0430</pubDate></item><item><title>کاوه نگار و اعتبار سنجی شماره تلفن</title><link>https://virgool.ir/@node.js.developers.kh/کاوه-نگار-و-اعتبار-سنجی-شماره-تلفن-fbhbswy2gx9i</link><description>میتونی بیشتر بخونی توی داک خودشون.از طریق این متد می‌توانید برای احراز هویت کاربران با ارسال کد اعتبار سنجی و یا اطلاعات ضروری مانند ارسال رمزعبور، کد تایید عضویت ، شماره فاکتور، کدهای خرید و تخفیف و ... استفاده نمائید. فرق این متد با متد ارسال پیامک در این است که پیامک های این متد بالاترین اولویت را دارند و هیچ کدام از پیامک های آن فیلتر نخواهند شد( ارسال پیامک به افرادی که پیامک تبلیغاتی خود را بسته اند) همچنین این متد قابلیت ارسال پیامک به ۱۴۸ کشور دنیا را دارد.برای مشاهده ویژگی های این سرویس به صفحه معرفی آن مراجعه کنید. (معرفی سرویس اعتبار سنجی)در ساختار این متد نیازی نیست فرستنده را ارسال کنید کافیست گیرنده و مقدار کد Token را ارسال نمائید. سیستم بهترین پیش شماره داخلی یا خارجی را انتخاب می کند و پیامک را ارسال می کند.برای استفاده از این متد نیاز است ابتدا الگوی پیام خود را از طریق پنل مشخص نمائید.ما از پکیج NPM ایشون استفاده میکنیم. import Kavenegar from &#39;kavenegar&#39;;&#xA;const kavenegar = Kavenegar.KavenegarApi({&#xA;    apikey: &#39;your key&#39;,&#xA;});&#xA;&#xA;function kave (payload) {&#xA;    return new Promise((resolve, reject) =&gt; {&#xA;        kavenegar.VerifyLookup(payload, (response, status, message) =&gt; {&#xA;            // you can also reject here based on the status.&#xA;            resolve({ response, status, message });&#xA;        });&#xA;    });&#xA;};و بعدش اینجوری استفاده بکنیش:await kave({&#xA;    template: &#39;verify-lead-after-submit&#39;,&#xA;    receptor: phone,&#xA;    token: verificationCode,&#xA;});توضیحات این پارامتر ها از داک خود کاوه نگارتوضیحات جوابی که کاوهنگار ممکنه بده:نکات تکمیلیپارامتر type دارای دو مقدار است call (در صورتی که نیاز به ارسال پیام صوتی دارید) و sms (در صورتی که نیاز به ارسال پیام متنی دارید).برای اطلاع از وضعیت پیامک به جدول وضعیت پیامک ها مراجعه نمائیدبرای پیامک به کشور های دیگر کد کشور را با دو صفر ارسال نمائیدبرای استفاده از این متد نیاز است سرویس پیشرفته را فعال نمائیددر صورت وجود اختلال در پیش شماره های داخلی ، پیامک از پیش شماره های بین المللی ارسال خواهد شددر صورت تمایل، واحد فنی توکن های بیشتری با قابلیت فضای خالی (Space) در اختیار شما قرار خواهد داد.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Mon, 12 Apr 2021 13:17:28 +0430</pubDate></item><item><title>کار با پکیج passportjs</title><link>https://virgool.ir/@node.js.developers.kh/کار-با-پکیج-passportjs-mfiks12khirx</link><description>بدون مقدمه سر اصل مطلبیه middleware هست. تنها هدفش: authenticate کردن ریکوئست هاس (پس یه موقع نیای توش authorization و ... هم بزاری. کد زدن ماژولار). قبلا فقط user name و password داشتیم. الان OAuth هم داریم. ما توی passport به هر کدوم از این مکانیزم های authentication یه strategy میگیم. هر کدوم هم یه پکیج جداگونه هستن.متد authenticate این متد یه middleware هست که بهش strategy رو میدی. این متد یه Connect middleware هست. به همین خاطر خیلی راحت میتونی توی expressjs ازش استفاده بکنی.به صورت پیشفرض 401 به عنوان جواب ریکوئستی که عملیات authetication اون fail شده، فرستاده میشه و اگه هم عملیات fail نشه middleware بعدی اجرا میشه و توی req.user اطلاعات کاربر قرار میگیره. حالا اگه بخوای پیام اختصاصی هر استراتژی رو سمت فرانت بفرستی باید failureFlash رو برابر با true بزاری:app.post(&#39;/login&#39;, passport.authenticate(&#39;local&#39;, { &#xA;    successRedirect: &#39;/&#39;, &#xA;    failureRedirect: &#39;/login&#39;,&#xA;    failureFlash: true }&#xA;));البته میتونی یه string هم به عنوان پیغام بزاری. برای اینکه این کار درست انجام بشه باید connect-flash نصب بشه.نکته: قبل از استفاده از این متد باید استراتژی ها config شده باشن.پاس دادن callback به این متدپارامتر های این متد:پارامتر err: اگه اروری رخ بده این پارامتر دارای مقدار خواهد بودپارامتر user: اگه عملیات fail بشه مقدار این پارامتر false میشهپارامتر info: اگه اون استراتژی مورد استفاده بخواد اطلاعات بیشتری برات بفرسته توی این پارامتر میریزه.app.get(&#39;/login&#39;, function(req, res, next) {&#xA;  passport.authenticate(&#39;local&#39;, function(err, user, info) {&#xA;    if (err) { return next(err); }&#xA;    if (!user) { return res.redirect(&#39;/login&#39;); }&#xA;    req.logIn(user, function(err) {&#xA;      if (err) { return next(err); }&#xA;      return res.redirect(&#39;/users/&#39; + user.username);&#xA;    });&#xA;  })(req, res, next);&#xA;});کانفیگ کردن استراتژی هابرای این منظور از passport.use استفاده میشه. </description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Mon, 12 Apr 2021 12:21:32 +0430</pubDate></item><item><title>کار با tmux</title><link>https://virgool.ir/CodeLovers/کار-با-tmux-dynlgwtqaoxq</link><description>این ابزار بهت کمک میکنه که خیلی راحت توی یه ترمینال بتونی یه عالمه ترمینال درست بکنی. نصبش خیلی ساده هست:sudo apt update&#xA;sudo apt-get install tmuxحالا برای اینکه وارد tmux بشی خیلی ساده توی ترمینال تایپ بکن tmux و اینتر رو بزن. برای تقسیم کردن عمودی صفحه نمایش به ۲ تا ترمینال میتونی ctrl + b و بعدش % + shift رو بزنی. برای تقسیم صفحه به صورت افقی هم همون  ctrl + b رو میزنی و بعدش &#34; + shift رو میزنی.برای جابجا شدن هم بین این ترمینال ها میتونی از ctrl + b و arrow key ها استفاده بکنی. امتحان بکنی خودت متوجه میشی. توی tmux اسکرول کردن توسط موس ممکن نیست (مگه تنظیمش بکنی). ولی راه ساده تر و سریعتر استفاده از ctrl + b و بعدش کلید ] رو فشار بدید. حالا با arrow key های بالا و پایین میتونید توی لاگ ها بالا و پایین بریدحالا فرض کن از tmux اومدی بیرون، یعنی detach کردی: برای detach کردن خیلی ساده میتونی ctrl + b رو بزنی و بعدش تایپ کنی :detachحالا برای اینکه لیست session های tmux رو ببینی میتونی از کامندی که این پایین نوشتم استفاده بکنی و session number های مختلف رو ببینیtmux list-sessions و برای اینکه به یه session خاص وصل بشی میتونی session number مورد نظر رو این جا بزاری:tmux attach -t session_number</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Tue, 30 Mar 2021 12:43:33 +0430</pubDate></item><item><title>کار با docker-compose</title><link>https://virgool.ir/@node.js.developers.kh/کار-با-docker-compose-zrojo00ntano</link><description>قبل از هر چیزی میخوام یه تعریف خوب از docker compose ارائه بدم؛ یه ابزار هست.چند تا کانتینر رو به صورت همزمان میتونه اجرا بکنه.یه فایل هست که توش تعریف میکنی چطوری باید اپلیکیشن هات راه اندازی بشن، چطوری با هم تعامل بکنن.اجزای یه docker compose فایلبخش servicesتوی این بخش میتونی اسم سرویس رو مشخص بکنی و بعدش دقیقا مشخص بکنی که اون سرویس چی هست.بخش imageتوی اینجا ایمیج base و ورژنش رو مشخص می کنیم.البته میتونیم که یه ترفند خوب بزنیم و ورژن امیج رو از env فایل بخونیم.نکته اینه که اگه ایمیج وجود نداشته باشه اون رو از docker registery میگیره (pull میکنه).اگه شما swarm داشته باشی و روی یکی از نود ها اون ایمیج وجود نداشته باشه، از نود های دیگه اون ایمیج رو روی اون نود کپی میکنن.بخش environmentتوی این بخش میایم متغیر هایی رو که دوست داریم به کانتینر پاس بدیم مشخص می کنیم.البته می تونیم این متغیر ها رو توی env فایل هم پاس بدیم.بخش ports توی این بخش میایم port mapping ها رو انجام میدیم.مثلا 8080:80 یعنی اینکه کانتینر port مون 80 هست و port ای که قراره expose بشه 8080 هست.بخش networksتوی این بخش میتونیم یک یا چند تا نتورک برای کانتینر مشخص بکنیم.البته اگه نتورک رو مشخص نکنیم خود داکر برای اون docker compose میاد نتورک default میسازه که اسمش از COMPOSE_PROJECT_NAME توی env فایل گرفته میشه. این بخش نتورک رو ایجاد نمیکنه (یه بخش جداگونه به اسم networks داریم که اون نتورک ها رو ایجاد میکنه)، بلکه فقط مشخص میکنه که من به کدوم نتورک وصل میشم. بخش volumesاین جا میایم volume های کانتینر رو مشخص می کنیم.توی همین جا هم میتونیم نوع volume و تنظیماتش رو مشخص بکنیم.بخش networksتوی اینجا تنظیمات network های custom رو مشخص بکنیم.بخش volumesتوی اینجا volume های custom رو مشخص می کنیم تا برامون بسازتش.کامند های docker compose برای ایجاد سرویس ها docker compose میتونی از کامند `docker-compose up` استفاده بکنی.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sat, 27 Mar 2021 15:12:40 +0430</pubDate></item><item><title>آمار بازدید پست‌های من در سال ۹۹</title><link>https://virgool.ir/@node.js.developers.kh/آمار-بازدید-پست-های-من-در-سال-۹۹-obnwumptfk4d</link><description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/eqchjodu5njc-bwm0C.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۳۳,۷۴۶ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۱۷۱ مرتبه پسندیدند و  ۱۶ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۴۰ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۱,۲۵۱ بار خوانده شدند و ۷۹۸,۸۲۹ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۱۰۹۵۱۸۶۵ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۱۰,۱۴۳ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۱۰۹۵۱۸۶۵ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Thu, 25 Mar 2021 10:33:17 +0430</pubDate></item><item><title>خرابکاری های رایج گیت برای junior هایی مثل من</title><link>https://virgool.ir/@node.js.developers.kh/خرابکاری-های-رایج-گیت-برای-junior-هایی-مثل-من-smkbhlqscqo9</link><description>یه مقدمه کوتاه بگم، توی این پست قصد دارم اشتباهات رایج خودم رو توی گیت بنویسم. پس خوشهالی و موثر بودن این پست رو با به اشتراک گذاشتن اشتباهات خودتون چند برابر بکنید (در ضمن اگه اشتباهتون خیلی مهم بود پست رو ویرایش می کنم و اونم به جمع اشتباهات رایج اضافه میشه). نکته مهم اینه که این پست هم مثل بقیه پست هام به روز رسانی میشه.اشتباهات مرتبط با merge کردن و undo کردن کامیتشماره ۱فرض کن برنچی داری با اسم location و توی اون اومدی یسری کامیت زدی و push کردی روی گیت هابت. بعدش اومدی تو برنچ order و اونو با برنچ location مرج کردی. حالا درجا یادت میفته که یه جایی از کدت ارور داره و اونو باید توی برنچ location درست بکنی.پس `git checkout location` میکنی و اون تیکه کد رو اصلاح میکنی، ولی دلت نمیخواد اون رو تو یه کامیت جدید بزنی. پس میای آخرین کامیتت رو undo میکنی و حالا دوباره با این تغییر جدید کامیت میزنی. و بعدش `git push --force origin location` میکنی. حالا `git checkout order` میکنی و برای اینکه تغییرات جدید رو داشته باشی برنچ order رو با location مرج میکنی. ولی یه موضوعی رو متوجه شدی دیگه! الان اون کامیت قبلیت توی برنچ order هست و هر دو کامیت وجو دارند. راه حل اینه که `git reset --hard commitSha` بکنی و دوباره مرج بکنی.اینفوگرافی خرابکاری خودم. دوستان اگه خیلی قشنگ نیست دلیلش اینه که خودم درستش کردم نه یه گرافیست.اینم از git log و گندی که باقی میمونهتوی این کیس شما میتونی `git reset --hard` بکنی روی کامیتی که پیامش a created هست و بعدی دوباره merge بکنی.شماره ۲یه کامیتی زدی با message اشتباه. حالا میخوای درستش کنی. کاری که میکنی اینه:اول یه `git log` میگیری تا بفهمی اون کامیتی که میخوای پیامش رو عوض بکنی بتونی انتخاب بکنی. از اول شروع به شمارش بکن. از شماره یک هم شروع کن. مثل آرایه ها نیست که از صفر شروع بکنه به شمارشحالا میای یه `git rebase -i HEAD~2` میزنی. (میخوایم message کامیت دوم رو عوض کنیم دیگه). یه nano (منظورم همون text editor ترمینال هست) برات باز میشه.pick b15304e fix (main.ts): jwt error middleware&#xA;pick 1eff0e0 add (user module)نوشته شده.  کاری که باید بکنی اینه که اون pick اولی رو به reword تغییر بدی و بعدش ctrl+x و shift+y بزنی تا تغییرات ذخیره بشه. (امیدوارم با nano کار کرده باشید و ازش نترسید:)حالا تو صفحه جدید دوباره همون ادیتوره باز میشه با یه تفاوت که حالا میتونی message رو عوض کنی. در نهایت هم  ctrl+x و shift+y بزن تا همه چی ذخیره بشه. تموم شد. به همین سادگی کامیت message رو عوض کردی.رفرنس این خرابکاری&lt;br/&gt;ادامه دارد...نظر فراموش نشه.اینستا گرام با همین ای دی. تلگرامم با آی دی nodejsdeveloperskh. </description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Wed, 10 Mar 2021 14:11:00 +0330</pubDate></item><item><title>جایگزین دستور deprecate شده apt-key add</title><link>https://virgool.ir/@node.js.developers.kh/جایگزین-دستور-deprecate-شده-apt-key-add-wylkucmsdiex</link><description>چند وقتی میشد که با این warning ترسناک روبرو میشدم. بالاخره امروز طلسم شکسته شد و تونستم با کمک gpg یه برنامه رو نصب بکنم (یعنی کلید عمومیش رو سیستم شناخت و از ریپوزیتوری دانش کرد). راستی من زیاد به اینکه چرا deprecated شد توجهی نشون ندادم ولی در کل به علت امنیت حذف شد.توی این مثال من داکر رو با این روش براتون نصب می کنم. داکیومنت مرجع برای نصب داکر هم اینه.خب فاز اول اینه که کلید رو درست بکنیم:مرحله اول اینه که بری توی دایرکتوری tmp. به خاطر اینکه چند تا فایل تهش میخوای تولید بکنی که از کل اون فایل ها فقط یکیشون به کارت میاد و از اونجایی که میدونید این دایرکتوری بعد از ریست شدن سیستم عامل تمام محتویاتش پاک میشه.$ cd /tmpمرحله بعد اینه که کلید رو دانلود بکنی:curl https://download.docker.com/linux/ubuntu/gpg 1&gt; docker.keyمرحله بعد مطمئن شدن از filetype با دستور file هست:file docker.keyخروجی باید همچین متنی توش باشه: `PGP public key block Public-Key (old)`مرحله بعد اینه که اون کلید رو import و export بکنی:gpg --no-default-keyring --keyring ./temp-docker.gpg --import docker.key&#xA;gpg --no-default-keyring --keyring ./temp-docker.pgp --export --output docker.gpgاگه بهتون گفت هیچی رو export نتونستم یعنی یه مشکلی دارید. پس تا زمانی که به درستی export نشده سراغ مراحل بعد نرید.حالا سراغ فاز بعدی که انتقال کلید و شناسوندنش باشه میریم:پیشنهاد من اینه که به صورت مستقیم این کلید رو توی دایرکتوری /etc/apt/trusted.gpg.d/ نریزید. بلکه بجاش یه دایرکتوری ایجاد کنید:mkdir -p /usr/local/share/keyrings/حالا اون کلید نهایی رو که `docker.gpg` باشه توی دایرکتوری بالا کپی کنید. آخر سر باید ریپوزیتوری داکر رو به سیستم معرفی بکنیم که اونم خیلی ساده هست:cd /etc/apt/sources.list.d/حالا یه فایل ایجاد میکنی به اسم docker.list و توش ریپوزیتوری داکر رو میریزیم:touch docker.list&#xA;echo &#34;deb [arch=amd64 /usr/local/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable&#34; &gt; docker.listحالا همه چی اوکی و فقط باید `apt update` زد و بعدش:apt install docker-ce docker-ce-cli containerd.ioو تموم. کل کاری که باید میکردی همین بود. حالا همین فرایند رو برای هر برنامه دیگه هم میتونی بری.برای حذف کلید های قدیمی هم میتونی این مراحل رو بری:اول لیستش کلید هایی که با دستور apt-key add اضافه کردی ببینی با این کامند: sudo apt-key list. توی تصویر زیر id کلید رو دورش یه کادر قرمز اندختم. ۲. حالا با دستور sudo apt-key del EFE21092 اون کلید رو پاک میکنی.نکته: نصب داکر شمال یه پیش نیاز هایی میشه که به علت نا مربوط بودن اینجا نگفتم، ولی شما میتونید تموم جزئیات رو توی اون لینکی که اول پس هست پیدا بکنی.رفرنس، رفرنس،</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sun, 21 Feb 2021 13:02:20 +0330</pubDate></item><item><title>فریم ورکی برای حل کردن مسائل و مشکلات برنامه نویسی</title><link>https://virgool.ir/CodeLovers/فریم-ورکی-برای-حل-کردن-مسائل-و-مشکلات-برنامه-نویسی-qjbme0v5dwu9</link><description>قبلا یه پست در مورد اینکه چجوری باید پروژه رو دیباگ کرد و اینکه چجوری باید با ارور ها برخورد کرد نوشته بودم که خیلی بی ربط به این موضوع نیست. ولی در کل برای حل هر مسئله ای که براتون رخ میده میتونید طبق این مراحلی که اینجا نوشتم جلو برید و مطمئن باشید که بهتون خیلی کمک میکنه و من خودمم از همین روش برای حل مشکلات برنامه نویسی خودم استفاده می کنم.این فریم ورک شامل ۷ یا ۸ تا مرحله هست:مرحله مشخص کردن سطح مسئلهاین مرحله برای زمانی بیشتر کاربرد داره که دارید به صورت تیمی کار می کنید و میخواید متناسب با هر شخص تقسیم مسئله رو انجام بدیم. حتی میتونی بهش این جوری نگاه بکنی که اگه مسئله خیلی پیچیده هست بدی برات انجام بدن و بعد روی جواب سعی کنی چیزای جدید یاد بگیری.اگه مسئله تو سطح ۴ یا ۵ باشه و تعداد دفعات زیادی این فریم ورک رو تا تهش رفتی و به نتیجه نرسیدی از یکی (مدیر فنی پروژه یا یه برنامه نویس دیگه که برات وقت بزاره) باید کمک بگیری.و اگه تو سطح ۱ تا ۳ بود باید این فریم ورک رو اونقدر تکرار بکنی تا اینکه مسئله حل بشه یا به سطح ۴ یا ۵ برسی.مرحله سوالاگه دارید تیمی کار می کنید باید به این موضوع هم فکر کنی: «آیا این مسئله به من مربوطه؟» شاید با همین یه سوال مسئله به کس دیگه ای محول بشه. البته یاد باشه که (مثل تصویر زیر) یه وقتی از اون ور بوم نیوفتی.سوالای درست پرسیدن به این معنی هست که تو مشکل رو به خوبی درک کردی که داری این سوال ها رو می پرسی. پس اگه نتونستی سوال درست بپرسی بدون که اصلا صورت مسئله رو درست نخوندی.یه مثال خیلی خیلی ساده میتونه این باشه که فرض کن بهت میگن یه کلاس بنویس که یه URL بگیره و بهش HTTP Request بزنه.سوالایی که من می پرسم ایناس:این کلاس قراره new بشه یا static باشه.در مورد http status ها قراره به چه شکل عمل بشه؟ API قراره فقط status code های ۲۰۰ و ۵۰۰ بده یا با http status code ها کار میشه.احراز هویتی هم قرار این کلاس انجام بده یا نهاگه پاسخ به سوال قبلی بله است، این کلاس با چند نوع احراز هویت قراره روبرو بشه.این کلاس قراره توکن های JWT رو مدیریت بکنه یا نه. اگه جاب سوال قبلی بله هست، آیا refreshToken و accessToken داریم. انقضای توکن های JWT چجوری هست. چک توکن رو قراره همین کلاس انجام بده یا نه...اگه مثل من مرضی به اسم کمال گرایی داری حتما حواست بهش باشه و گرنه اصلا مسئله رو حل نمیتونی و سوالایی هم که می پرسی زاییده ی کمال گراییت هست و (شاید) به حل مسئله کمک نکنه و فقط مسئله رو برات هیولا بسازهاگه کمال گرایی درست بود هیچ وقت نباید برج پیزایی ساخته میشد.اگه پیش درآمد دارید در مورد اون مسئله، حتما قبل از وارد شدن به مسئله اونا رو از ذهنتون خالی بکنید و با یه ذهن باز به سراغ مسئله برید.برای حل مسئله Deadline تعیین کن تا خودت رو مقید به انجامش بکنی.استراتژی divide &amp; conquer مسئله رو بشکن و هر زیر مسئله رو در ساده ترین شکل ببین. استراتژی کالباسی برای حل مسائل پیچیده خیلی خوبه.تحقیق بکنتوی گوگل، stackoverflow و هر جایی که میتونی سرچ بزن.فیلم های آموزشی youtube رو ببیننمونه کد ها رو توی github و gitlab ببینمقاله های medium و سایت های دیگه رو بخونانگلیسی و فارسی سرچ کن.شبه کد / الگوریتم / فلو چارتاگه بازم مسئله سخته سعی کن براش الگوریتم/شبه کد بنویسی. فلوچارت بکش.مرحله استراحتاگه مشکلت حل نشد یه ۱۵ تا ۲۰ دقیقه به ذهنت آرامش بده. برو دراز بکش، کتاب بخون و بزار ذهنت آزاد بشه. بعد دوباره از مرحله اول شروع بکن. اگه بازم بعد از ۳ یا ۴ بار مشکلت حل نشده باقی موند بزار از روش ۲۴ ساعت بگذره و بعد دوباره همین فریم ورک رو از مرحله یک شروع بکن.یادداشت کردناگه میخوای یادت نره کجا بودی از یه نرم افزار مثل CherryTree استفاده بکن.در انتها باید این فیلم رو هم بزارم که بخشی از این فریم ورک رو مدیونش هستم: https://www.aparat.com/v/CZyMl اگه کلیه قسمت های این ویدئو رو بعلاوه یه سری آموزش های دیگه که از نظر من برای یادگیری برنامه نویسی لازمه رو میخوای میتونید از طریق تلگرام با من در ارتباط باشید. آی دی تلگرام: mjbKhorasani</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sun, 14 Feb 2021 15:22:21 +0330</pubDate></item><item><title>تنظیمات prettierrc</title><link>https://virgool.ir/@node.js.developers.kh/تنظیمات-prettierrc-w4ozeky0emuk</link><description>قبل از اینکه بریم سر وقت کانفیگ کردن prettier اول بیاید extension اش رو نصب بکنیم. Ctrl + Shift + X رو بزنید و prettier رو سرچ و نصب کنید. بعد برید توی تنظیمات VSCode خودتون (کلید میانبرش کنترل و کاما هست)، default formatter رو سرچ کنید و روی esbenp.prettier-vscode بزارید.کانفیگ کردن prettierrc یه فایل کف پروژه میسازید که مثل json هست. اسم فایل رو هم دقیقا `.prettierrc` بزارید.همون طور که می بینید gitignore نشده. چونکه قراره کل اعضای تیم با همین کانفیگ کار بکنن تا همه به یه شکل کد بزنن. کانفیگ های این فایل رو میتونید به فرمت yaml یا json بنویسید.کانفیگ printWidthطول هر خط رو مشخص میکنه. حتما دقت کردید که توی VSCode خط و ستون رو نشون میده. این کانفیگ میگه دوست داری هر line چند تا col داشته باشه. این کانفیگ حداکثر رو مشخص نمیکنه. یعنی ممکنه یه خط از کدت بیشتر از مقداری که تنظیم کردی بشه، ولی در کل سعی میکنه طول خطوط رو نزدیک اون مقدار در نظر بگیره. مقداری که من براش انتخاب کردن `60` هست که اونم به دلیل خوانایی هست. البته شما میتونید `70` یا `80` رو هم امتحان کنید.کانفیگ - tabWidthتعداد فاصله (white space) هایی رو که قرار هست به ازای هر indent بزنه مشخص میکنه. معمولا ۲ یا ۴ میزارنش.کانفیگ - useTabsاین کانفیگ مشخص میکنه که tab بزنم یا space. اگه مقدار true بهش بدی بجای space از tab استفاده میکنه. و اگه false بدی از space استفاده میکنه.کانفیگ - semiبرای اینکه خوش ته هر statement یه `;` بزاره میتونید مقدار این کانفیگ رو true بدید. ولی اگه false بدی شاید به یه سری مشکلات بر بخوری.کانفیگ - singleQuoteاگه false بهش بدی تا جایی که براش ممکن باشه به جای double quote از single quote استفاده میکنه. مثلا &#34;I&#39;m double quoted&#34; خودش میمونه. ولی &#34;This \&#34;example\&#34; is single quoted&#34; به &#39;This &#34;example&#34; is single quoted&#39; تبدیل میشه.کانفیگ - quotePropsاین کانفیگ دور کلید های آبجکت رو quote میزاره و سه مقدار مختلف میتونه بگیره:&#34;as-needed&#34;/&#34;consistent&#34;/&#34;preserve&#34;مقدار اولی میگه اگه لازم بود دور کلید آبجکت quote بنداز. که به صورت پیشفرض همین مقدار هست.مقدار دومی میگه اگه حتی یه کلید هم quote داشت تمام کلید ها رو quote دار بکن.کانفیگ - trailingCommaافزودن کاما به انتهای statement ها و expression هایی که ممکنه تهشون کاما قرار داد. مثلا توی دستور زیر کاما نمتوان ته expression قرار داد.const arr1 = [1];سه تا مقدار میگیره:مقدار `&#34;none&#34;` که هیچ وقت کاما نمیزاره.مقدار `&#34;es5&#34;` که مطابق قوانین es5 کاما میزاره. مقدار پیشفرض همینه.مقدار `&#34;all&#34;` هم باعث میشه همیشه کاما رو بزاره.کانفیگ bracketSpacingفاصله (white space) بین bracket ها توی object literal ها میزاره. true و false میگیره: true یعنی space بزاره. و false نمیزاره:{ foo: &#39;bar&#39; } // true&#xA;{foo: &#39;bar&#39;} // falseکانفیگ arrowParensاگه مقدار `&#34;always&#34;` رو بهش بدی همیشه پرانتز دور arrow function ها میندازه و اگه `&#34;avoid&#34;` بهش بدی تا زمانی که نیاز نباشه نمیندازه.(x) =&gt; x // &#34;always&#34;&#xA;x =&gt; x // &#34;avoid&#34;کانفیگ requirePragmaوقتی میخوای فقط یه سری فایل هایی که اولین خطشون یه کامنت خاصی دارن رو prettier بکنی این کانفیگ رو true میکنی. مقدار پیشفرضش false هست. Add this comment:&#xA;/**&#xA; * @prettier&#xA; */&#xA;Or this one:&#xA;/**&#xA; * @format&#xA; */کانفیگ endOfLineوقتی تیمی کار می کنید ممکنه روی چند سیستم عامل مختلف باشید و روی هر سیستم عامل end of line رو به یه شکل مشخص می کنن. این موضوع باعث میشه که وقتی `git diff` یا `git blame` میگیری به مشکل بخوری. پس حتما مطمئن شو که این رو روی `&#34;lf&#34;` تنظیم بکنی.&#34;lf&#34; = \n (Linux/MacOS)&#xA;&#34;crlf&#34; = \r\n (Windows)&#xA;&#34;cr&#34; = \r&#xA;&#34;auto&#34;اینم یه کانفیگ عمومی که به نظرم به کار اکثر دولوپرا بیاد.{&#xA;    &#34;arrowParens&#34;: &#34;always&#34;,&#xA;    &#34;useTabs&#34;: false,&#xA;    &#34;bracketSpacing&#34;: true,&#xA;    &#34;endOfLine&#34;: &#34;lf&#34;,&#xA;    &#34;printWidth&#34;: 70,&#xA;    &#34;quoteProps&#34;: &#34;as-needed&#34;,&#xA;    &#34;tabWidth&#34;: 4,&#xA;    &#34;trailingComma&#34;: &#34;all&#34;,&#xA;    &#34;semi&#34;: true,&#xA;    &#34;singleQuote&#34;: true,&#xA;    &#34;overrides&#34;: [&#xA;        {&#xA;            &#34;files&#34;: &#34;*.yml&#34;,&#xA;            &#34;options&#34;: {&#xA;                &#34;singleQuote&#34;: false,&#xA;                &#34;tabWidth&#34;: 2&#xA;            }&#xA;        }&#xA;    ]&#xA;}Prettier Cheat sheet در ضمن میتونی cheat sheet اش رو که خودم نوشتم از این جا دان کنی. نکات تکمیلیاگه یه پروژه داری که کلش رو بدون prettier نوشتی ولی الان میخوای prettier رو بهش اضافه بکنی یه روش خیلی ساده برای اینکه کل فایل ها رو prettier بکنی اینه که از کامند لاین prettier استفاده بکنی، برای همین من تو خیلی از پروژه هام یکی از اسکریپت های فایل package.json رو این میزارم&#34;scripts&#34;: {&#xA;    &#34;prettier&#34;: &#34;prettier --write &#39;**/*.js&#39; &#39;**/*.ts&#39;&#34;, // or&#xA;    &#34;format&#34;: &#34;prettier --write &#39;**/*.js&#39;; prettier --write &#39;**/*.ts&#39;; prettier --write &#39;**/*.json&#39;&#34;&#xA;}رفرنس این نکته این issue ای هست که تو گیت هاب زدن.</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Sat, 13 Feb 2021 13:10:56 +0330</pubDate></item><item><title>تست full text search با دیتاست های دیجی کالا</title><link>https://virgool.ir/@node.js.developers.kh/تست-full-text-search-با-دیتاست-های-دیجی-کالا-n239s7q14a8s</link><description>قبلش پست های دیگه منو در مورد full text search و ایندکس گذاری در PostgreSQL بخونید.قبل از همه از اینجا دیتاست محصولاتش (که اسم فایلش 5-awte8wbd هست) رو دانلود کنید. مرحله بعد ایجاد یه دیتابیس PostgreSQL ای توی داکر هست. حالا بیاید دیتابیس رو ایجاد بکنید و بعدش کوئری زیر رو اجرا کنید:create table products (&#xA;  id bigint primary key,&#xA;  product_title_fa varchar(255),&#xA;  product_title_en varchar(255),&#xA;  url_code varchar(255),&#xA;  title_alt varchar(255), &#xA;  category_title_fa varchar(255), &#xA;  category_keywords varchar(255),&#xA;  brand_name_fa varchar(255),&#xA;  brand_name_en varchar(255),&#xA;  product_attributes varchar(5500)&#xA;);بعدش با دستور docker cp فایل رو توی کانتینر بزارید و بعدش کوئری زیر رو اجرا کنید:COPY products FROM &#39;/tmp/5-awte8wbd.csv&#39; WITH CSV HEADER;مرحله بعد افزودن ستون جدید هست:alter table products add column __search tsvector;حالا میایم اون ستون رو مقدار دهی می کنیم:update products p set __search = to_tsvector(p.product_title_fa);بعدش ستون جدید رو ایندکس گذاری با متد GIN ایندکس گذاری می کنیم.create index idx_products__search on products using GIN(__search);حالا بیاید این دو تا کوئری رو با هم مقایسه بکنیم:explain analyse select count (*) from products where __search @@ to_tsquery(&#39;سرمه&#39;);نتیجه اینه:کوئری دوم اینه:explain analyse select count (*) from products where product_title_fa like &#39;%سرمه%&#39;;نتیجه اینه:یه چیزی در حدود ۵۰ برابر سریعتر شد اجرای کوئری!رفرنس ۱</description><category>Mohammad Jawad Barati</category><author>Mohammad Jawad Barati</author><pubDate>Wed, 06 Jan 2021 17:06:58 +0330</pubDate></item></channel></rss>