uz
Feedback
ToCode

ToCode

Kanalga Telegramโ€™da oโ€˜tish

ื˜ื™ืคื™ื ืงืฆืจื™ื ืœืžืชื›ื ืชื™ื ืžืืช ื™ื ื•ืŸ ืคืจืง

Ko'proq ko'rsatish
1 419
Obunachilar
Ma'lumot yo'q24 soatlar
-17 kunlar
+230 kunlar
Postlar arxiv
ToCode
1 419
# ืื•ื›ืœ ื™ืฉืŸ ื‘ืžืงืจืจ ืจื•ื‘ ื”ืื ืฉื™ื ืžืฆืœื™ื—ื™ื ืœื–ื”ื•ืช ื“ื™ ื˜ื•ื‘ ืงื•ืคืกืื•ืช ืคืœืกื˜ื™ืง ืฉืฉื•ื›ื‘ื•ืช ื‘ืžืงืจืจ ื™ื•ืชืจ ืžื“ื™ ื–ืžืŸ ืขื“ ืฉื›ื‘ืจ ืื™ ืืคืฉืจ ืœืื›ื•ืœ ืืช ืžื” ืฉื™ืฉ ื‘ืคื ื™ื. ื•ืจื•ื‘ ื”ืžืื›ืœื™ื ื’ื ืฉื•ืจื“ื™ื ื™ื•ืชืจ ืžื›ืžื” ืฉืขื•ืช ื‘ืชื•ืš ืื•ืชื” ืงื•ืคืกืช ืคืœืกื˜ื™ืง. ื”ื–ืžืŸ ืฉื‘ืืžืฆืข ื”ื•ื ื”ื—ืœืง ื”ืžืขื ื™ื™ืŸ: ื›ืœ ื”ืคืขืžื™ื ืฉืื ื™ ืžืกืชื›ืœ ืขืœ ื”ืงื•ืคืกื” ื›ืฉื”ืื•ื›ืœ ืขื“ื™ื™ืŸ ืœื ืžืžืฉ ืจืงื•ื‘ ื•ืžืชืœื‘ื˜ ืื ืœืื›ื•ืœ, ื•ืื– ื‘ืกื•ืฃ ื™ื•ืจื“ ืžื–ื” ื›ื™ ื”ื•ื ื›ื‘ืจ ื™ื•ืฉื‘ ืฉื ื›ืžื” ื™ืžื™ื ืื‘ืœ ืขื“ื™ื™ืŸ ืฉื•ืžืจ ืืช ื”ืงื•ืคืกื” ื›ื™ ืžื™ ื™ื•ื“ืข ื•ืื•ืœื™ ืคืขื ื”ื‘ืื” ืื ื™ ืื”ื™ื” ืžืกืคื™ืง ืจืขื‘ ื‘ืฉื‘ื™ืœ ืœืื›ื•ืœ ืื•ืชื• ... ื•ื™ื•ืชืจ ืžื“ื™ ืžืชื›ื ืชื™ื ืฉืื ื™ ืžื›ื™ืจ, ื›ืฉืžืชื—ื™ืœื™ื ืœื›ืชื•ื‘ ืงื•ื“ ืœื ืื™ื“ืืœื™ ื ืงืฉืจื™ื ืืœื™ื• ื›ืžื• ืœืื•ืชื” ืงื•ืคืกื” ืฉืื ื™ ืžื—ื–ื™ืง ื‘ืžืงืจืจ. ื‘ืžืงื•ื ืœืžื—ื•ืง ืืช ืžื” ืฉืœื ืขื•ื‘ื“ ื‘ืื•ืชื• ืจื’ืข ื”ื ืžืขื“ื™ืคื™ื ืœื”ืžืฉื™ืš ืขื ืื•ืชื• ืงื• ืžื—ืฉื‘ื” ืฉืœื ื”ืฆืœื™ื— ื•ืœื‘ื ื•ืช ืขื•ื“ ืžืขืงืฃ ืงื˜ืŸ ืขื ืขื•ื“ ืคื’ื™ืขื” ืงื˜ื ื” ื‘ื‘ื™ืฆื•ืขื™ื. ืื ื—ื ื• ื™ื•ื“ืขื™ื ืฉื‘ืขืชื™ื“ ื–ื” ื™ื’ื™ืข ืœืžืฆื‘ ืฉื›ื‘ืจ ืื™ ืืคืฉืจ ืœืชื—ื–ืง ืื•ืชื•, ืื‘ืœ ื›ืจื’ืข ื”ืžืฆื‘ ืœื ื›ื–ื” ื’ืจื•ืข ื•ืฆืจื™ืš ืœื”ืชืงื“ื ืขื ื”ืคื™ืฆ'ืจ. ืžื” - ืœืžื—ื•ืง ืงื•ื“ ืฉืื ื™ ื›ื‘ืจ ืฉื‘ื•ืขื™ื™ื ืขื•ื‘ื“ ืขืœื™ื•? ืœื—ื–ื•ืจ ืขื›ืฉื™ื• ืœื ืงื•ื“ืช ื”ื”ืชื—ืœื”? ืื™ืš ืžืกื‘ื™ืจื™ื ืœื‘ื•ืก ื›ื–ื” ื“ื‘ืจ? ื•ืื™ืš ืžืกื‘ื™ืจื™ื ืืช ื–ื” ืœืขืฆืžื™? ืื– ืžืžืฉื™ื›ื™ื ืขื ื”ืคื™ืฆ'ืจ ื›ื™ ืžืžืฉื™ื›ื™ื ื•ื‘ืกื•ืฃ ืื—ืจื™ ืฉื ื” ื™ื•ืฆืื™ื ืœืจื™ืคืงื˜ื•ืจื™ื ื’ ื’ื“ื•ืœ ื›ื™ ื›ื‘ืจ ืื™ ืืคืฉืจ ืœืชื—ื–ืง ืืช ื›ื“ื•ืจ ื”ื‘ื•ืฅ ื”ืขื ืง ืฉืื ื—ื ื• ืงื•ืจืื™ื ืœื• ืงื•ื“. ื”ืจื‘ื” ื™ื•ืชืจ ืงืœ ืœื–ืจื•ืง ืืช ื”ืื•ื›ืœ ื•ืืช ื”ืงื•ื“ ื›ืฉืžื–ื”ื™ื ืืช ื”ืกื™ืžื ื™ื ื”ืจืืฉื•ื ื™ื ืฉืœ ื”ืจื™ืงื‘ื•ืŸ. ืื‘ืกื˜ืจืงืฆื™ื” ื’ืจื•ืขื” ืœื ืชืฉืชืคืจ ืคื™ืชืื•ื ื›ื™ ื™ืขื‘ื•ืจ ืขื•ื“ ืฉื‘ื•ืข, ืœื”ื™ืคืš, ื”ื™ื ืจืง ืชื”ื™ื” ื™ื•ืชืจ ื’ืจื•ืขื” ื›ื™ ืขื•ื“ ื•ืขื•ื“ ืงื•ื“ ื‘ืžืขืจื›ืช ื™ื•ืขืชืง ืžืžื ื” ื•ื™ืฉืชืžืฉ ื‘ื”. ื”ืฉื‘ื•ืขื™ื™ื ืื—ื•ืจื” ืฉืืชื ื—ื•ื–ืจื™ื? ื–ื” ื”ืจื‘ื” ื™ื•ืชืจ ืงืฆืจ ืžืฉื‘ื•ืขื™ื™ื (ื›ื™ ืืชื ื›ื‘ืจ ื™ื•ื“ืขื™ื ืžื” ืฆืจื™ืš ืœื‘ื ื•ืช ื•ืžื” ื”ื“ืจืš ื”ื ื›ื•ื ื” ืœื‘ื ื•ืช ืื•ืชื•), ื•ื”ื—ื™ืกื›ื•ืŸ ื‘ื–ืžืŸ ื‘ืฉื ื” ื”ืงืจื•ื‘ื” ื™ื”ื™ื” ื”ืจื‘ื” ื™ื•ืชืจ ื’ื“ื•ืœ.

ToCode
1 419
ื ืกื• ืœืžืฆื•ื ืื™ืš ืœืฉื ื•ืช ืืช ืกื“ืจ ื”ืžื™ื•ืŸ ื›ื“ื™ ืœืžืฆื•ื ืืช ื”ืžืฉืชืžืฉ ืขื ื”ื›ื™ ืคื—ื•ืช ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช, ื•ืื– ืœืžืฆื•ื ืืช ื”ืžืฉืชืžืฉ ืขื ื”ื›ื™ ื”ืจื‘ื” ืžืฉื™ืžื•ืช ืกื’ื•ืจื•ืช. ## ื™ืฆื™ืจืช ืขื ืŸ ืชื’ื™ื•ืช ืžื›ืœ ื”ืชื’ื™ื•ืช ื‘ื›ืœ ื”ืžืฉื™ืžื•ืช ื”ื“ื•ื’ืžื” ื”ืื—ืจื•ื ื” ืœืคื•ืกื˜ ื•ื”ื—ื‘ื™ื‘ื” ืขืœื™ื™ ื‘ื™ื•ืชืจ ื”ื™ื ื”ื™ื›ื•ืœืช ืœืงื—ืช ืืช ื›ืœ ื”ืขืจื›ื™ื ืžืฉื“ื” ืฉื ืฉืžืจ ื‘ืชื•ืจ ืžืขืจืš ื•ืœื™ืฆื•ืจ ืžื”ื ืงื‘ื•ืฆื” ืื—ืช ื’ื“ื•ืœื” ืฉืžื›ื™ืœื” ืืช ื›ื•ืœื. ื–ื” ืขื•ื–ืจ ื›ืฉื™ืฉ ืœื ื• ืœืžืฉืœ ืจืฉื™ืžืช ืชื’ื™ื•ืช ื•ืื ื—ื ื• ืจื•ืฆื™ื ืœื™ื™ืฆืจ ืขื ืŸ ืชื’ื™ื•ืช ืื• ืคืฉื•ื˜ ืœื”ืฆื™ื’ ื‘ืฆื“ ืฉืœ ื”ืžืกืš ืจืฉื™ืžื” ืฉืœ ื›ืœ ื”ืชื’ื™ื•ืช ื”ืืคืฉืจื™ื•ืช. ื” Pipeline ื”ืจืืฉื•ืŸ ืœื•ืงื— ืืช ืฉื“ื” tags ื•ืžื•ืฆื™ื ืืช ื›ืœ ื”ืขืจื›ื™ื ื”ื—ื•ืฆื” ืžื”ืžืขืจืš ื›ื“ื™ ืฉื ื•ื›ืœ ืœืฉื—ืง ืื™ืชื ื‘ืืžืฆืขื•ืช ืฉืœื‘ unwind, ืื—ืจื™ ื–ื” ื”ื•ื ืžืืจื’ืŸ ืืช ื›ื•ืœื ื‘ืงื‘ื•ืฆื•ืช ืื‘ืœ ืฉื™ืžื• ืœื‘ ืœืžื–ื”ื” ืฉื‘ื—ืจืชื™ - ืคืฉื•ื˜ null. ืžื–ื”ื” ื–ื” ื”ื•ื ื–ื”ื” ืœื›ืœ ื”ืžืกืžื›ื™ื ื•ืœื›ืŸ ื ืงื‘ืœ ืจืง ืžืกืžืš ืื—ื“ ื‘ืชื•ืฆืื”. ื”ืฉื“ื” tags ืฉืœ ืื•ืชื• ืžืกืžืš ื‘ืชื•ืฆืื” ืžื›ื™ืœ ืืช ื”ืชื•ืฆืื” ืฉืœ ืคืงื•ื“ืช $addToSet, ืฉืœื•ืงื—ืช ืžื›ืœ ืžืกืžืš ืืช ืฉื“ื” tags ืฉืœื• ื•ืžื•ืกื™ืคื” ืื•ืชื• ืœืงื‘ื•ืฆื”:
db.collection.aggregate([
  {
    "$unwind": "$tags"
  },
  {
    "$group": {
      _id: null,
      tags: {
        "$addToSet": "$tags"
      }
    }
  },
  
])
ืืชื ืžื•ื–ืžื ื™ื ืœืฉื—ืง ืขื ื”ืฉืื™ืœืชื” ื›ืืŸ: https://mongoplayground.net/p/2sxnLVSARWl ื ืกื• ืœื”ื•ืจื™ื“ ืืช ื” $unwind ื•ืชืจืื• ืื ืืชื ืžืฆืœื™ื—ื™ื ืœื ื—ืฉ ืžื” ื™ืงืจื”. ืืคืฉืจื•ืช ืฉื ื™ื” ื•ื™ื•ืชืจ ืžื•ืขื™ืœื” ื”ื™ื ืœื”ื•ืกื™ืฃ ืœื›ืœ ืชื’ื™ืช ื’ื ืืช ืžืกืคืจ ื”ืžืกืžื›ื™ื ืฉืžืชื•ื™ื’ื™ื ื‘ืชื’ื™ืช ื–ื•. ื‘ืฉื‘ื™ืœ ื–ื” ืื ื™ ืžืฉืชืžืฉ ื‘ tags ื‘ืชื•ืจ ื”ืžื–ื”ื” ื›ื“ื™ ืฉื›ืœ ื”ืžืกืžื›ื™ื ืฉื™ืฉ ืœื”ื ืืช ืื•ืชื” ืชื’ื™ืช ื™ื”ื™ื• ื‘ืื•ืชื” ืงื‘ื•ืฆื”, ื•ืžื•ืกื™ืฃ ืœื”ื ืฉื“ื” ื‘ืฉื count ืฉืžื›ื™ืœ ืืช ืžืกืคืจ ื”ืžืกืžื›ื™ื ื‘ืงื‘ื•ืฆื”:
db.collection.aggregate([
  {
    "$unwind": "$tags"
  },
  {
    "$group": {
      _id: "$tags",
      "count": {
        "$count": {}
      }
    }
  },
])
ืฆืจื™ืš ืœื”ื’ื™ื“: ื”ืชื—ื‘ื™ืจ ืฉืœ Aggregation Pipeline ื”ื•ื ืœื ืื”ื‘ื” ืžืžื‘ื˜ ืจืืฉื•ืŸ. ื™ืฉ ื”ืžื•ืŸ ืคืงื•ื“ื•ืช ื•ืœืžืจื•ืช ื–ืืช ืœืคืขืžื™ื ืืชื ืœื ืžื•ืฆืื™ื ื‘ื“ื™ื•ืง ืืช ื”ืคืงื•ื“ื” ืฉืืชื ืฆืจื™ื›ื™ื, ื•ืœืคืขืžื™ื ืฆืจื™ืš ืœืžืฆื•ื ื“ืจื›ื™ื ื™ืฆื™ืจืชื™ื•ืช ื›ื“ื™ ืœื’ืจื•ื ืœ Pipeline ืœื‘ืฆืข ื‘ื“ื™ื•ืง ืืช ื”ื—ื™ืฉื•ื‘ ืฉืจื•ืฆื™ื. ื•ืขื“ื™ื™ืŸ, ืื—ืจื™ ืงืฆืช ืื™ืžื•ื ื™ื ืืชื ืชืจืื• ืฉ Pipelines ืžืฆืœื™ื—ื™ื ืœืชืช ืคื™ืชืจื•ืŸ ืœื ืคื—ื•ืช ื˜ื•ื‘ (ื•ืื•ืœื™ ืœืคืขืžื™ื ืงืฆืช ื™ื•ืชืจ ื˜ื•ื‘) ืž SQL.

ToCode
1 419
ืื—ืจื™ ืฉื”ืฉืœื‘ ื”ืจืืฉื•ืŸ ืžืกืชื™ื™ื ื•ื™ืฉ ืœื ื• ืืช ื”ืงื‘ื•ืฆื•ืช ืžื•ื ื’ื• ืžืžืฉื™ืš ืœืฉืœื‘ ื”ืฉื ื™ ืฉื›ื•ืœืœ ืคืงื•ื“ืช $match. ืคืงื•ื“ื” ื–ื• ืžืกื ื ืช ืืช ื”ืžืกืžื›ื™ื (ื›ืœื•ืžืจ ืืช ื”ืงื‘ื•ืฆื•ืช) ืœืคื™ ื”ืคืจืžื˜ืจ ืฉืงื™ื‘ืœื”. ื‘ Pipeline ื”ื“ื•ื’ืžื” ื”ืคืจืžื˜ืจ ื”ื–ื” ื”ื’ื“ื™ืจ ืฉื”ืฉื“ื” totalSaleAmount ื™ื”ื™ื” ื’ื“ื•ืœ ืื• ืฉื•ื•ื” ืœ 100, ื•ืœื›ืŸ ืจืง ื”ืงื‘ื•ืฆื•ืช ืฉืžืชืื™ืžื•ืช ื™ื•ืคื™ืขื• ื‘ืชื•ืฆืื”. ืกืš ื”ื›ืœ ืชื•ืฆืืช ื” Pipeline ืชื”ื™ื”:
{ "_id" : "abc", "totalSaleAmount" : NumberDecimal("170") }
{ "_id" : "xyz", "totalSaleAmount" : NumberDecimal("150") }
{ "_id" : "def", "totalSaleAmount" : NumberDecimal("112.5") }
ื ืžืฉื™ืš ืœืขื•ื“ ื›ืžื” ื“ื•ื’ืžืื•ืช ื•ื”ืคืขื ืขืœ ืื•ืกืฃ ื ืชื•ื ื™ื ืฉืœ ืžืฉื™ืžื•ืช. ## ื™ืฆื™ืจืช ื”ื ืชื•ื ื™ื ืืœื” ื”ื ืชื•ื ื™ื ืœื“ื•ื’ืžื” ื‘ Collection ืฉืœื™. ื™ืฉ ืคื” ืžืฉื™ืžื•ืช ืœื‘ื™ืฆื•ืข, ืœื›ืœ ืžืฉื™ืžื” ื™ืฉ ืกื˜ื˜ื•ืก (ื‘ืฉื“ื” done) ื”ืื ื‘ื•ืฆืขื” ืื• ืœื, ืžืฉืชืžืฉ ืฉื”ืžืฉื™ืžื” ื‘ื‘ืขืœื•ืชื•, ื˜ืงืกื˜ ืฉืœ ื”ืžืฉื™ืžื” ื•ืจืฉื™ืžืช ืชื’ื™ื•ืช:
[
  {
    "key": 1,
    text: "do it!",
    done: false,
    owner: "dan",
    tags: [
      "home"
    ],
  },
  {
    "key": 2,
    text: "do something else",
    done: false,
    owner: "mike",
    tags: [
      "home",
      "work"
    ],
  },
  {
    key: 3,
    text: "fix stuff",
    done: true,
    owner: "mike",
    tags: [
      "home",
      "garden"
    ],
  },
  {
    key: 4,
    text: "eat something",
    done: false,
    owner: "mike",
    tags: [],
  }
]
## ืกืคื™ืจืช ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ืฉืœ ื›ืœ ื”ืžืฉืชืžืฉื™ื ืžืฉื™ืžื” ืจืืฉื•ื ื” ื”ื™ื ืœืžืฆื•ื ื›ืžื” ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ื™ืฉ ืกืš ื”ื›ืœ ืœื›ืœ ืฉืžืฉืชืžืฉื™ื ื™ื—ื“. ืฉืชื™ ื”ืคืงื•ื“ื•ืช ืฉื™ืขื–ืจื• ืœื ื• ื›ืืŸ ื”ืŸ $match ื• $count: ื”ืจืืฉื•ื ื” ืชืกื ืŸ ืจืง ืืช ื”ืžืฉื™ืžื•ืช ืฉืขื“ื™ื™ืŸ ืœื ื‘ื•ืฆืขื•, ื•ื”ืฉื ื™ื” ืชืกืคื•ืจ ื›ืžื” ืžืฉื™ืžื•ืช ื›ืืœื” ื”ื™ื•. ื›ืš ื ืจืื” ื” Pipeline:
db.collection.aggregate([
  {
    $match: {
      done: false
    }
  },
  {
    $count: "totalOpenTasks",
    
  }
])
ื•ืื ืืชื ืจื•ืฆื™ื ืœืฉื—ืง ืขื ื”ืงื•ื“, ืœื”ืจื™ืฅ ื“ืจืš ื”ื“ืคื“ืคืŸ ืื• ืœืฉื ื•ืช ืงืฆืช ื•ืœืจืื•ืช ืืช ื”ืืคืงื˜ ื”ื›ื ืชื™ ื“ืฃ ื‘ Mongo Playground ืฉืžืชืื™ื ื•ื”ื•ื ืžื—ื›ื” ืœื›ื ื‘ืงื™ืฉื•ืจ ื›ืืŸ: https://mongoplayground.net/p/QwZCzp4etfd ## ืกืคื™ืจืช ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ืฉืœ ืžืฉืชืžืฉ ืžืกื•ื™ื ื•ืžื” ืื ื ืจืฆื” ืœื”ืชืื™ื ืืช ื”ืฉืื™ืœืชื” ืจืง ืœืžืฉืชืžืฉ ืžืกื•ื™ื? ื”ื›ืœ ืงืœ ื‘ืขื•ืœื, ืจืง ืฆืจื™ืš ืœืฉื ื•ืช ืืช ื”ืชื ืื™ ื‘ $match. ื›ืš ื™ืจืื” ื”ืงื•ื“:
db.collection.aggregate([
  {
    $match: {
      done: false,
      owner: "dan",
      
    }
  },
  {
    $count: "dansOpenTasks",
  }
])
ื•ื›ืืŸ ื™ืฉ ืืช ื” Mongo Playground ื”ืžืชืื™ื ืœื•: https://mongoplayground.net/p/s08WtYHrjbp ## ื™ืฆื™ืจืช ื“ื•ื—: ื›ืžื” ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ื™ืฉ ืœื›ืœ ืžืฉืชืžืฉ ื‘ื•ืื• ื ืกื‘ืš ืงืฆืช ืืช ื”ืขื ื™ื™ื ื™ื ื•ื ืฉืืœ ื›ืžื” ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ื™ืฉ ืœื›ืœ ืื—ื“ ืžื”ืžืฉืชืžืฉื™ื ื‘ืžืขืจื›ืช. ืื ื ื“ืžื™ื™ืŸ ืืช ื” Pipeline ืื– ื‘ืฉื‘ื™ืœ ืžืฉื™ืžื” ื›ื–ืืช ืฆืจื™ืš ืœื”ื—ืœื™ืฃ ืืช ื”ืคืงื•ื“ื” ื”ืฉื ื™ื”, ื‘ืžืงื•ื ืœืกืคื•ืจ ื›ืžื” ืžืกืžื›ื™ื ืงื™ื‘ืœื ื•, ื ืจืฆื” ืœืงื‘ืฅ ื™ื—ื“ ืœืงื‘ื•ืฆื•ืช ืืช ื”ืžืฉื™ืžื•ืช ืœืคื™ ืฉื“ื” owner (ื›ืœื•ืžืจ ืœืคื™ ื”ืžืฉืชืžืฉ ืฉื”ืžืฉื™ืžื” ืฉื™ื™ื›ืช ืœื•), ื•ืœืกืคื•ืจ ื›ืžื” ืžืกืžื›ื™ื ื™ืฉ ื‘ื›ืœ ืงื‘ื•ืฆื” ื›ื–ืืช. ื”ืชื—ื‘ื™ืจ ืงืฆืช ืžืกื•ืจื‘ืœ ื•ื”ื•ื ื ืจืื” ื›ืš:
db.collection.aggregate([
  {
    $match: {
      done: false,
    }
  },
  {
    $group: {
      "_id": "$owner",
      "openTasks": {
        $count: {}
      }
    }
  }
])
ื•ืคื” ืืคืฉืจ ืœืฉื—ืง ืขื ื”ืฉืื™ืœืชื”: https://mongoplayground.net/p/7FhgRMgHFvE ## ื–ื™ื”ื•ื™ ื”ืžืฉืชืžืฉ ืขื ื”ื›ื™ ื”ืจื‘ื” ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ืื—ืจื™ ืฉื’ื™ืœื™ื ื• ื›ืžื” ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช ื™ืฉ ืœื›ืœ ืžืฉืชืžืฉ ืืคืฉืจ ืœื”ืžืฉื™ืš ื•ืœื—ืคืฉ ืืช ื”ืžืฉืชืžืฉ ืฉื™ืฉ ืœื• ื”ื›ื™ ื”ืจื‘ื” ืžืฉื™ืžื•ืช ืคืชื•ื—ื•ืช. ื–ื• ืžืฉื™ืžื” ืฉืขืฉื•ื™ื” ืœื‘ืœื‘ืœ ื›ื™ ืื™ืŸ ื‘ Aggregation Pipeline ืคืขื•ืœื” ืฉืœ Max ืฉืžื—ื–ื™ืจื” ืืช ื”ืžืกืžืš ืขื ื”ืขืจืš ื”ืžืงืกื™ืžืœื™. ื‘ืžืงื•ื ื–ื” ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื”ืฉืชืžืฉ ื‘ืžื™ื•ืŸ ื•ื‘ limit. ื–ื” ืงืฆืช ืžื‘ืœื‘ืœ ื›ื™ sort ื ืฉืžืข ื›ืžื• ืžืฉื”ื• ืฉืœื•ืงื— ื™ื•ืชืจ ื–ืžืŸ ืžื—ื™ืฉื•ื‘ ืขืจืš ืžืงืกื™ืžืœื™, ืื‘ืœ ืžื•ื ื’ื• ืžืกืคื™ืง ื—ื›ื ื‘ืฉื‘ื™ืœ ืœื–ื”ื•ืช ืืช ื”ืชื‘ื ื™ืช ื”ื–ืืช ื•ืœื ืœืžื™ื™ืŸ ื‘ืืžืช ืืช ื›ืœ ื”ืžืกืžื›ื™ื. ื”ื ื” ื”ืงื•ื“:
db.collection.aggregate([
  {
    $match: {
      done: false,
    }
  },
  {
    $group: {
      "_id": "$owner",
      "openTasks": {
        $count: {}
      }
    }
  },
  {
    "$sort": {
      "openTasks": -1
    }
  },
  {
    $limit: 1,
  }
])
ืฉื‘ืืžืช ื™ื™ืชืŸ ืืช ื”ืชื•ืฆืื”:
[
  {
    "_id": "mike",
    "openTasks": 2
  }
]
ื•ืืชื ื™ื›ื•ืœื™ื ืœืฉื—ืง ืื™ืชื• ื‘ืงื™ืฉื•ืจ ื”ื–ื”: https://mongoplayground.net/p/fUtBp28Cakb.

ToCode
1 419
# ืžื“ืจื™ืš ืงืฆืจ ืœืื’ืจื’ืฆื™ื•ืช ื‘ MongoDB ืื—ื“ ื”ืคื™ืฆ'ืจื™ื ื”ืื”ื•ื‘ื™ื ืขืœื™ื™ ื‘ MongoDB ื”ื•ื ื”ื™ื›ื•ืœืช ืœื—ื‘ืจ ื™ื—ื“ ืžืกืžื›ื™ื ืœืงื‘ืœืช ืชื•ืฆืื” ื‘ืืžืฆืขื•ืช ืžื™ื ื™ ืฉืคืช ืชื›ื ื•ืช ืฉืœื”ื ืฉื ืงืจืืช Aggregation Pipeline. ืื’ื™ื“ ืœื›ื ืืช ื”ืืžืช ืื”ื‘ื” ืžืžื‘ื˜ ืจืืฉื•ืŸ ืœื ื”ื™ืชื” ืฉื, ืื‘ืœ ืื—ืจื™ ืฉืœืžื“ืชื™ ืœื”ืฉืชืžืฉ ื‘ืคื™ืฆ'ืจ ื•ืœื”ืชืžืฆื ื‘ืชื™ืขื•ื“ ืฉืœื”ื ื”ื—ื™ื™ื ืฉืœื™ ืขื ืžื•ื ื’ื• ื”ืฉืชืคืจื• ืžืฉืžืขื•ืชื™ืช. ื‘ื•ืื• ื ืจืื” ืื™ืš ื–ื” ืขื•ื‘ื“. ## ืžื”ื• Aggregation Pipeline ื“ืžื™ื™ื ื• ืฉืคืช ืชื›ื ื•ืช ืจืง ืฉื”ืชื•ื›ื ื™ืช ืฉืืชื ื›ื•ืชื‘ื™ื ื‘ื” ืจืฆื” ืขืœ ืงืœื˜ ืžืื•ื“ ืกืคืฆื™ืคื™: ืจืฉื™ืžืช ืžืกืžื›ื™ื ืž Mongo ืฉืžืชืื™ืžื™ื ืœืงืจื™ื˜ืจื™ื•ืŸ ืžืกื•ื™ื. ื›ืœ ืคืงื•ื“ื” ื‘ืชื•ื›ื ื™ืช ืขื•ืฉื” ืžืฉื”ื• ืขื ื”ืงืœื˜ ื”ื–ื”, ืœืžืฉืœ ืชื”ื™ื” ืคืงื•ื“ื” ืฉืชื•ืกื™ืฃ ืฉื“ื” ืœื›ืœ ืžืกืžืš, ืคืงื•ื“ื” ืื—ืจืช ืฉืžืกื ื ืช ื”ื—ื•ืฆื” ื—ืœืง ืžื”ืžืกืžื›ื™ื, ืคืงื•ื“ื” ืฉืœื™ืฉื™ืช ืฉืžืฉืื™ืจื” ืจืง ืฉื“ื•ืช ืžืกื•ื™ืžื™ื ืฉืœ ื”ืžืกืžื›ื™ื ื•ืคืงื•ื“ื” ืจื‘ื™ืขื™ืช ืฉืžืื—ื“ืช ืžืกืžื›ื™ื ืฉื•ื ื™ื ืœืงื‘ื•ืฆื”. ื”ืคืงื•ื“ื•ืช ื”ืืœื” ื ืงืจืื•ืช Aggregation Stages ื•ืืคืฉืจ ืœืžืฆื•ื ืจืฉื™ืžื” ืฉืœื”ืŸ ื•ืคื™ืจื•ื˜ ืขืœ ื›ืœ ืื—ืช ื‘ื“ืฃ ื”ืชื™ืขื•ื“ ื›ืืŸ: https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/. ื•ื›ืŸ ื›ืœ Stage ื›ื–ื” ืžืงื‘ืœ ืคืจืžื˜ืจื™ื ืฉืื•ืžืจื™ื ืœื• ืื™ืš ื‘ื“ื™ื•ืง ืœืขืฉื•ืช ืืช ื”ื“ื‘ืจ ืฉืœื•, ืœืžืฉืœ ื”ืคืงื•ื“ื” $count ืžื—ืœื™ืคื” ืืช ื›ืœ ื”ืžืกืžื›ื™ื ื‘ืžืกืžืš ืขื ืฉื“ื” ื‘ื•ื“ื“ ืฉื”ืขืจืš ืฉืœื• ื”ื•ื ื›ืžื” ืžืกืžื›ื™ื ืขื‘ืจื• ื“ืจื›ื”. ื”ื™ื ืชืงื‘ืœ ืคืจืžื˜ืจ ืฉื™ื’ื™ื“ ืœื” ืžื” ืฉื ื”ืฉื“ื” ืฉื™ื”ื™ื” ื‘ืžืกืžืš ื”ืชื•ืฆืื”. ื”ืคืงื•ื“ื” $match ืžืกื ื ืช ืืช ื”ืžืกืžื›ื™ื ืฉืขื•ื‘ืจื™ื ื“ืจื›ื” ื•ืชืชืŸ ืจืง ืœืžืกืžื›ื™ื ืžืกื•ื™ืžื™ื ืœืขื‘ื•ืจ. ื”ื™ื ืชืงื‘ืœ ืคืจืžื˜ืจ ืฉืื•ืžืจ ืœืื™ื–ื” ืžืกืžื›ื™ื ืžื•ืชืจ ืœื”ืžืฉื™ืš. ืืช ื” Pipeline ืื ื—ื ื• ื›ื•ืชื‘ื™ื ื‘ืชื•ืจ ืจืฆืฃ ืฉืœ ืคืงื•ื“ื•ืช ื‘ืชื•ืš ืžืขืจืš, ื•ื›ืœ ืคืงื•ื“ื” ื”ื™ื ืื•ื‘ื™ืงื˜ JavaScript. ื–ื” ืชื—ื‘ื™ืจ ืฉืœื•ืงื— ื–ืžืŸ ืœื”ืชืจื’ืœ ืืœื™ื•. ื”ื ื” ื“ื•ื’ืžื” ืœ Pipeline:
  [
    // First Stage
    {
      $group :
        {
          _id : "$item",
          totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }
        }
     },
     // Second Stage
     {
       $match: { "totalSaleAmount": { $gte: 100 } }
     }
   ]
ื™ืฉ ืคื” ืฉืชื™ ืคืงื•ื“ื•ืช: ื”ืคืงื•ื“ื” ื”ืจืืฉื•ื ื” ื”ื™ื ืคืงื•ื“ืช $group ื•ื”ืฉื ื™ื” ืคืงื•ื“ืช $match. ืขื›ืฉื™ื• ื‘ื•ืื• ื ื“ืžื™ื™ืŸ ื›ืžื” ืžืกืžื›ื™ Mongo ืฉื”ื•ืœื›ื™ื ืœืขื‘ื•ืจ ื“ืจืš ื” Pipeline ื”ื–ื”. ืื•ืœื™ ื”ื ื ืจืื™ื ื›ืš:
[
  { "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") },
  { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") },
  { "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") },
  { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" :  NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") },
  { "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") },
  { "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") },
  { "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") },
  { "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") },
]
ื”ืคืงื•ื“ื” ื”ืจืืฉื•ื ื” ื”ื™ื ืคืงื•ื“ืช $group ืฉืžืงื‘ืœืช ื‘ืชื•ืจ ืคืจืžื˜ืจ ืื•ื‘ื™ืงื˜. ื”ืื•ื‘ื™ืงื˜ ืžืชืืจ ืื™ืš ื™ืจืื• ื”ืงื‘ื•ืฆื•ืช ืฉืื ื—ื ื• ื‘ื•ื ื™ื. ื”ื•ื ืžื›ื™ืœ ืฉื“ื” ื‘ืฉื _id ืขื ื”ืขืจืš $item, ืฉื–ื” ืื•ืžืจ ื‘ืขื‘ืจื™ืช ืฉื›ืœ ืงื‘ื•ืฆื” ืชื”ื™ื” ืžื–ื•ื”ื” ืœืคื™ ื”ืขืจืš ืฉืœ ืฉื“ื” item ืฉืœ ื›ืœ ืžืกืžืš. ืื– ื”ืžืกืžืš ื”ืจืืฉื•ืŸ ืžื’ื™ืข ื• Mongo ืžืกืชื›ืœ ืขืœ ืฉื“ื” item ืฉืœื• ื•ืจื•ืื” ืืช ื”ืขืจืš abc, ืžื‘ื™ืŸ ืฉืื™ืŸ ืขื“ื™ื™ืŸ ืžืกืžืš ื›ื–ื” ื‘ืชื•ืฆืื” ื•ื ื•ืชืŸ ืœื• ืœืขื‘ื•ืจ. ืื—ืจื™ ื–ื” ืขื•ื‘ืจื™ื ืขื•ื“ ื›ืžื” ืžืกืžื›ื™ื ืขื“ ืฉืžื’ื™ืขื™ื ืœืžืกืžืš ื”ื—ืžื™ืฉื™ ืฉืฉื•ื‘ ืžื›ื™ืœ ื‘ืฉื“ื” item ืืช ืื•ืชื• ืขืจืš abc. ื”ืคืขื ืžื•ื ื’ื• ืžื–ื”ื” ืฉื”ื•ื ื›ื‘ืจ ืจืื” ืืช ื”ืขืจืš ื”ื–ื” ื•ืžื•ืกื™ืฃ ืืช ื”ืžืกืžืš ื”ื—ืžื™ืฉื™ ืœืื•ืชื” ืงื‘ื•ืฆื” ื™ื—ื“ ืขื ื”ืžืกืžืš ื”ืจืืฉื•ืŸ. ืื ื—ื ื• ื™ื•ื“ืขื™ื ืฉื›ืœ ื”ืžืกืžื›ื™ื ื‘ืื•ืชื” ืงื‘ื•ืฆื” ืžื›ื™ืœื™ื ืืช ืื•ืชื• ืขืจืš ืœืฉื“ื” _id ืฉืœื”ื, ื›ื™ ื›ื›ื” ื‘ื ื™ื ื• ืืช ื”ืงื‘ื•ืฆื•ืช, ืื‘ืœ ืžื” ืœื’ื‘ื™ ื”ืฉื“ื•ืช ื”ืื—ืจื™ื? ืื– ืื ื—ื ื• ืจื•ืื™ื ืฉื”ืคืจืžื˜ืจ ืฉ $group ืงื™ื‘ืœ ื”ื™ื” ืื•ื‘ื™ืงื˜ ื•ื™ืฉ ืฉื ื‘ืืžืช ืžืคืชื— ื ื•ืกืฃ ื‘ืฉื totalSaleAmount. ืžืคืชื— ื ื•ืกืฃ ืžื’ื“ื™ืจ ืฉื™ื”ื™ื” ืฉื“ื” ื ื•ืกืฃ ื‘ืื•ื‘ื™ืงื˜ ื”ืชื•ืฆืื”, ื•ื”ืขืจืš ืฉืœ ื”ืฉื“ื” ื™ื”ื™ื” ื”ื—ื™ืฉื•ื‘ ืฉืื ื—ื ื• ืจื•ืฉืžื™ื ื‘ืื•ื‘ื™ืงื˜ - ื›ืœื•ืžืจ ืกื›ื•ื ืฉืœ ืžื›ืคืœื•ืช ื”ืžื—ื™ืจ ื‘ื›ืžื•ืช. ื‘ื›ืœ ืžืกืžืš ืฉืžื’ื™ืข ืžื•ื ื’ื• ื™ื™ืงื— ืืช ื”ืžื—ื™ืจ, ื™ื›ืคื™ืœ ืื•ืชื• ื‘ื›ืžื•ืช ื•ื™ื•ืกื™ืฃ ืืช ื–ื” ืœืขืจืš ืฉืฉืžื•ืจ ืœื• ืขื‘ื•ืจ ื”ืงื‘ื•ืฆื”.

ToCode
1 419
# ืฉืืœื•ืช ืžืจืื™ื•ื ื•ืช ืขื‘ื•ื“ื”: ื›ื™ื•ื•ืฅ ืžื—ืจื•ื–ื•ืช ื ืชืงืœืชื™ ื‘ืžืงืจื” ื‘ืฉืืœื” ื”ื–ืืช ืฉื”ื–ื›ื™ืจื” ืœื™ ื›ืžื” ื—ืฉื•ื‘ ืœื”ื›ื™ืจ ื‘ื™ื˜ื•ื™ื™ื ืจื’ื•ืœืืจื™ื™ื, ื•ืœื• ืจืง ื‘ืฉื‘ื™ืœ ืœื”ืจื’ื™ื– ืืช ื”ืžืจืื™ื™ื ื™ื ืฉืœื›ื ืฉืฉื•ืืœื™ื ืฉืืœื•ืช ื˜ื™ืคืฉื™ื•ืช ื‘ืจืื™ื•ื ื•ืช ืขื‘ื•ื“ื”. ื”ืžืฉื—ืง ื”ื•ื ื›ื–ื” - ื‘ื”ื™ื ืชืŸ ืžื—ืจื•ื–ืช ืขืœื™ื›ื "ืœื›ื•ื•ืฅ" ืืช ื”ืžื—ืจื•ื–ืช ื‘ืืžืฆืขื•ืช ื”ื—ืœืคืช ื›ืœ ืจืฆืฃ ืฉืœ ืื•ืชื™ื•ืช ื‘ืื•ืช ืื—ืช ืžื”ืจืฆืฃ ื•ืื—ืจื™ื” ืžืกืคืจ ื”ืื•ืชื™ื•ืช ื‘ืจืฆืฃ. ืœื“ื•ื’ืžื” ืื ื”ืžื—ืจื•ื–ืช ื”ืžืงื•ืจื™ืช ื”ื™ื:
aaaabbccc
ืื– ืื ื—ื ื• ืžื—ืœื™ืคื™ื ืืช ืจืฆืฃ ื” a-ื™ื ื‘ a4, ืืช ืจืฆืฃ ื” b-ื™ื ื‘ b2 ื•ืืช ืจืฆืฃ ื” c-ื™ื ื‘ c3 ื•ืžืงื‘ืœื™ื:
a4b2c3
ืื ื”ืชื•ืฆืื” ืืจื•ื›ื” ื™ื•ืชืจ ืžื”ืžื—ืจื•ื–ืช ื”ืžืงื•ืจื™ืช ื™ืฉ ืœื”ื—ื–ื™ืจ ืืช ื”ืžื—ืจื•ื–ืช ื”ืžืงื•ืจื™ืช, ื•ืื ื”ืชื•ืฆืื” ืงืฆืจื” ื™ื•ืชืจ ื™ืฉ ืœื”ื—ื–ื™ืจ ืืช ื”ืชื•ืฆืื” ื”ืžื›ื•ื•ืฆืช. ## ืคื™ืชืจื•ืŸ ื›ืœ ืคืขื ืฉืื ื™ ืฉื•ืžืข "ืจืฆืฃ ืฉืœ ืื•ืชื™ื•ืช" ื‘ืฉืืœื” ืžื”ืกื•ื’ ื”ื–ื” ืžื™ื“ ืื ื™ ื—ื•ืฉื‘ ืขืœ ื‘ื™ื˜ื•ื™ื™ื ืจื’ื•ืœืืจื™ื™ื. ื‘ื‘ื™ื˜ื•ื™ ืจื’ื•ืœืืจื™ ืื ื™ ื™ื›ื•ืœ ืœืกื’ื•ืจ ืงื˜ืข ืžืกื•ื™ื ืฉืžืฆืืชื™ ื‘ืกื•ื’ืจื™ื™ื ื•ืื– ืœื”ืชื™ื—ืก ืืœื™ื• ืฉื•ื‘ ื‘ืืžืฆืขื•ืช \1. ืœื›ืŸ ืจืฆืฃ ืฉืœ ืื•ืชื™ื•ืช ื”ื•ื ื‘ืกืš ื”ื›ืœ ื”ืฆื™ืจื•ืฃ (\w)\1+ ืื• ืื ื”ืจืฆืฃ ื™ื›ื•ืœ ืœื”ื™ื•ืช ื’ื ื‘ืื•ืจืš 1 ื–ื” ื™ื”ื™ื” (\w)\1*. ื‘ืฉื‘ื™ืœ ืœื›ื•ื•ืฅ ืžื—ืจื•ื–ืช ืžืกืคื™ืง ืœืžืฆื•ื ืจืฆืฃ ื›ื–ื” ื•ืœื”ื—ืœื™ืฃ ืื•ืชื• ื‘ืื•ืช ื”ืจืืฉื•ื ื” ืžืžื ื• ื•ืื—ืจื™ื” ืื•ืจืš ื”ืจืฆืฃ. ื”ืงื•ื“ ื‘ืฉื•ืจื” ืื—ืช ืฉืœ ืคื™ื™ืชื•ืŸ ื•ืขื ืคื•ื ืงืฆื™ื™ืช ื‘ื“ื™ืงื” ืœื™ื“ื• ื™ืจืื” ื›ืš:
import re

def compress(original):
    compressed =  re.sub(
            r'(\w)\1*',
            lambda m: m[0][0] + str(len(m[0])),
            original)
    return compressed if len(compressed) < len(original) else original

def test_compress():
    assert compress("a")       == "a"
    assert compress("aaa")     == "a3"
    assert compress("aaabbb")  == "a3b3"
    assert compress("aaabccc") == "a3b1c3"

ToCode
1 419
# ื”ืชื•ืจ ื‘ืคื•ื˜ื• ืฆืคื•ืŸ ื›ืœ ืฉื ื” ื‘ื™ื•ื ื”ืื—ืจื•ืŸ ืœืคื ื™ ืฉื—ื•ื–ืจื™ื ืœืœื™ืžื•ื“ื™ื ืืคืฉืจ ืœืจืื•ืช ืชื•ืจ ืฉืœ ืขืฉืจื•ืช ื”ื•ืจื™ื ืžื™ื•ื–ืขื™ื ืขื•ืžื“ื™ื ื‘ื™ื”ื•ื“ื” ืžื›ื‘ื™ ืžื—ื•ืฅ ืœืคื•ื˜ื• ืฆืคื•ืŸ - ื—ื ื•ืช ืคื™ืชื•ื— ื”ืชืžื•ื ื•ืช ื”ื™ื—ื™ื“ื” ื‘ืกื‘ื™ื‘ื”. ื›ื•ืœื ืงื™ื‘ืœื• ื™ื•ื ืงื•ื“ื ืืช ืจืฉื™ืžืช ื”ืฆื™ื•ื“ ืœื’ืŸ ืฉื›ื•ืœืœืช ืชืžื•ื ื” ืฉืœ ื”ืคืฉื•ืฉ ืื• ื”ืคืฉื•ืฉื™ืช ื‘ืฉื‘ื™ืœ ืœืชืœื•ืช ืขืœ ื”ืงื™ืจ, ืืฆืœ ื›ื•ืœื ื”ืชืžื•ื ื•ืช ื‘ื˜ืœืคื•ืŸ ื•ืœื ื‘ืืœื‘ื•ืžื™ื ื•ื›ื•ืœื ืžื—ื›ื™ื ื‘ืฉืžืฉ ื•ืžืงื•ื•ื™ื ืฉืœื ื™ืกื’ืจื• ืœืคื ื™ ืฉื™ื’ื™ืข ืชื•ืจื. ื”ืชื•ืจ ืœืชืžื•ื ื” ื”ื•ื ืื—ื“ ื”ืชื•ืจื™ื ืฉื”ื›ื™ ืงืœ ืœื—ืกื•ืš. ืฆืจื™ืš ืจืง ืœืชื›ื ืŸ ืงื“ื™ืžื” ื•ืœืœื›ืช ืœืคืชื— ืืช ื”ืชืžื•ื ื” ืœืคื ื™ ืืกื™ืคืช ื”ื”ื•ืจื™ื ื•ืœืคื ื™ ืฉืžื—ืœืงื™ื ืืช ืจืฉื™ืžืช ื”ืฆื™ื•ื“. ื–ื” ืœื Over Engineering ืœื”ืกืชื›ืœ ืงื“ื™ืžื” ืœื“ื‘ืจ ืฉืื ื—ื ื• ื™ื•ื“ืขื™ื ืฉื™ืงืจื”. ื–ื” ืœื Over Engineering ืœืขืฉื•ืช ืฉื™ืขื•ืจื™ ื‘ื™ืช, ืœื‘ื“ื•ืง ืžื” ืงืจื” ื‘ืฉื ื” ืฉืขื‘ืจื” ืื• ืžื” ืงื•ืจื” ื‘ื’ื ื™ื ืื—ืจื™ื. ื–ื” ืœื Over Engineering ื•ื–ื” ืœื YAGNI ืืคื™ืœื• ืื ืฉืœื—ืช ืชืžื•ื ื” ืœืคื™ืชื•ื— ื•ื‘ืกื•ืฃ ื”ื—ืœื™ื˜ื• ื‘ื’ืŸ ืœื•ื•ืชืจ ืขืœ ื”ืชืžื•ื ื•ืช ื”ืฉื ื”. ืชื›ื ื•ืŸ ืงื“ื™ืžื” ื”ื•ื ืชืžื™ื“ ืžืฉื—ืง ืฉืœ ืกื™ื›ื•ื ื™ื ื•ืกื™ื›ื•ื™ื™ื ื•ื”ื•ื ื”ืžืฉื—ืง ืฉืื ืฉื™ ืžืงืฆื•ืข ืžืฉื—ืงื™ื ื›ืœ ื™ื•ื. ื‘ื•ืื• ืขื ื ืชื•ื ื™ื ื•ืชืกื‘ื™ืจื• ืžื” ืืชื ื—ื•ืฉื‘ื™ื ืฉื”ื•ืœืš ืœืงืจื•ืช ื•ืื™ืš ื”ืชื›ื ื•ืŸ ืฉืœื›ื ื™ืขื–ื•ืจ ื›ืฉื–ื” ื™ืงืจื”. ื–ื” ื”ื‘ืกื™ืก ืœ Engineering ืžื“ื•ื™ืง.

ToCode
1 419
# ืงืจื™ื˜ืจื™ื•ืŸ ื”ืื ื”ื•ื ืคื•ืชืจ ื‘ืขื™ื•ืช ืžื”ืจ? ื”ืื ื”ื•ื ืจื•ืื” ืืช ื›ืœ ืžืงืจื™ ื”ืงืฆื” ื”ืจืœื•ื•ื ื˜ื™ื™ื? ื”ืื ื”ืคื™ืชืจื•ื ื•ืช ืฉืœื” ืชืžื™ื“ ื”ื›ื™ ื™ืขื™ืœื™ื? ื”ืื ื”ืชืงืฉื•ืจืช ืื™ืชื” ื˜ื•ื‘ื”? ื”ืื ื”ื•ื ื™ืชืืžืฅ ืœืคืชื•ืจ ื‘ืขื™ื” ื‘ื›ื•ื—ื•ืช ืขืฆืžื•? ื”ืื ื”ื•ื ื™ื“ืข ืœื‘ืงืฉ ืขื–ืจื” ื›ืฉืฆืจื™ืš? ื”ืื ื”ื™ื ืชืกื›ื™ื ืœืœืžื•ื“ ื˜ื›ื ื•ืœื•ื’ื™ื” ื—ื“ืฉื” ื›ืฉื”ืคืจื•ื™ืงื˜ ื“ื•ืจืฉ ืืช ื–ื”? ื”ืื ื”ื™ื ืœื•ืžื“ืช ืžื”ืจ? ืจืื™ื•ื ื•ืช ืขื‘ื•ื“ื” ื”ื•ืœื›ื™ื ืœืคื™ ืชื‘ื ื™ืช. ื–ื” ื”ื’ื™ื•ื ื™ ื›ื™ ื”ืื ืฉื™ื ืฉืžืขื‘ื™ืจื™ื ืืช ื”ืจืื™ื•ื ื•ืช ื™ื•ื“ืขื™ื ืœื‘ื—ื•ืŸ ืžื•ืขืžื“ื™ื ื›ืžื• ืฉืชืžื™ื“ ื‘ื—ื ื• ื•ื›ืžื• ืฉื‘ื—ื ื• ืื•ืชื: ืื ื—ื ื• ื ื•ืชื ื™ื ืฉืืœื•ืช ืžืงืฆื•ืขื™ื•ืช ื•ืจื•ืื™ื ืื™ืš ื”ื‘ืŸ ืื“ื ืžืชืคืงื“ ื‘ืชื•ืš ื”ืฉืืœื•ืช ื”ืืœื”. ื”ื™ื•ื ืขื ื›ืœ ื”ืขื‘ื•ื“ื” ืžืจื—ื•ืง ืื ื™ ืžื•ืฆื ื”ืžื•ืŸ ืจืื™ื•ื ื•ืช ืขื‘ื•ื“ื” ืžื•ืงืœื˜ื™ื ื‘ื™ื•ื˜ื™ื•ื‘ ืฉืžืจืื™ื ืืช ืื•ืชื• ืฉื˜ืื ืฅ ืฉื•ื‘ ื•ืฉื•ื‘. ื”ืžื—ืฉื‘ื” "ืื ื™ ืื“ืข ืฉื–ื” ื–ื” ื›ืฉืืจืื” ืืช ื–ื”" ื”ืคื›ื” ืœืงื• ื”ืžื•ื‘ื™ืœ, ื•ื–ื” ืœืคืขืžื™ื ืžืจื’ื™ืฉ ืžืฆืคื™ื” ื‘ืจืื™ื•ื ื•ืช ื”ืืœื” ืฉื›ื•ืœื ืžื—ืคืฉื™ื ืืช ืื•ืชื• ื“ื‘ืจ ื‘ื“ื™ื•ืง. ื‘ื›ืœ ื’ื™ื•ืก ื™ืฉ Trade Offs ื•ื–ืืช ืชืžื™ื“ ื”ืชืœื‘ื˜ื•ืช ื‘ื™ืŸ ื”ื”ื™ื ืฉื”ืฆื™ื’ื” ืืช ื”ืคื™ืชืจื•ืŸ ื”ื™ืขื™ืœ ื‘ื™ื•ืชืจ ืœื”ื•ื ืฉื”ืฆืœื™ื— ืœืชืงืฉืจ ื™ื•ืชืจ ื˜ื•ื‘ ืืช ืชื”ืœื™ืš ื”ืžื—ืฉื‘ื” ืฉืœื•. ืื ื’ื ืืชื ืชืงื•ืขื™ื ื•ืœื ืžืฆืœื™ื—ื™ื ืœืžืฆื•ื ืืช ื”ืžื•ืขืžื“ ื”ืžื•ืฉืœื, ืื•ืœื™ ืฉื•ื•ื” ืœืขืฆื•ืจ ืจื’ืข ื•ืœื—ืฉื•ื‘ ืžื—ื“ืฉ ืขืœ ื”ืงืจื™ื˜ืจื™ื•ื ื™ื. ืฉื™ื ื•ื™ ืงื˜ืŸ ื‘ืงืจื™ื˜ืจื™ื•ื ื™ื ื™ื›ื•ืœ ืœืคืชื•ื— ืœื›ื ืขื•ืœื ื—ื“ืฉ ืฉืœ ื”ื–ื“ืžื ื•ื™ื•ืช, ืื•ืœื™ ื˜ื•ื‘ื•ืช ื‘ื”ืจื‘ื” ืžืืœื” ืฉื‘ื“ืงืชื ืขื“ ืขื›ืฉื™ื•.

ToCode
1 419
ื”ื—ืœืง ื”ืื—ืจื•ืŸ ื‘ืžืกืœื•ืœ ืฉืœื ื• ื ืงืจื ื” Resolver ืื• ื” rootValue. ื–ื” ื”ืžื™ืžื•ืฉ ืฉืœ ื”ืกื›ื™ืžื”, ื›ืœื•ืžืจ ืื•ื‘ื™ืงื˜ ื” JavaScript ืฉืžื—ื‘ืจ ื‘ื™ืŸ ื”ืกื›ื™ืžื” ืœืฉื›ื‘ืช ื”ื ืชื•ื ื™ื. ื›ืš ื”ื•ื ื ืจืื” ื‘ืžื ื”ืœ ื”ืžืฉื™ืžื•ืช ืฉืœื™:
const db = require('../dl/tasks');

module.exports = {
  tasks: (args) => {
    return db.getTasks();
  },
  task: (args) => {
    const { id } = args;
    return db.getTask(id);
  },
  toggleTask: async (args) => {
    const { id } = args;
    await db.toggleTask(id);
    return await db.getTask(id);
  }
};
ืฉืœื•ืฉืช ื”ืคื•ื ืงืฆื™ื•ืช ืžืชืื™ืžื•ืช ืœืฉืœื•ืฉืช ื”ืฉื“ื•ืช ื‘ืื•ื‘ื™ืงื˜ื™ื ื”ืžื™ื•ื—ื“ื™ื Query ื• Mutation. ื”ืกื›ื™ืžื” ื”ื’ื“ื™ืจื” ืฉ Task ื”ื•ื ืขืœื” (leaf) ื•ืฉื™ืฉ ืœื• ืืช ื”ืฉื“ื•ืช title, description ื• done, ื•ืœื›ืŸ GraphQL ืžืฆืคื” ืœืงื‘ืœ ื‘ื—ื–ืจื” ืžื”ืคื•ื ืงืฆื™ื•ืช ืื•ื‘ื™ืงื˜ ืื• ืื•ื‘ื™ืงื˜ื™ื ืขื ืฉื“ื•ืช ืืœื”. ืื’ื‘ ื”ื•ื ืžื•ื›ืŸ ืœื”ืชืคืฉืจ ื•ืœืงื‘ืœ Promise ืฉื™ื—ื–ื™ืจ ืื•ื‘ื™ืงื˜ ืขื ืฉื“ื•ืช ืืœื”, ื•ื–ื” ืžื” ืฉืื ื—ื ื• ืขื•ืฉื™ื ื‘ื“ื•ื’ืžื” ื›ืืŸ. ## ืื™ืš ืžืจื™ืฆื™ื ื•ืฉืื™ืœืชื•ืช ืœื“ื•ื’ืžื” ื‘ืคื•ืกื˜ ื”ื“ื‘ืงืชื™ ืจืง ืืช ื”ืงื•ื“ ืฉื ืจืื” ืœื™ ืžืขื ื™ื™ืŸ ื‘ืฉื‘ื™ืœ ืœื”ื‘ื™ืŸ ืืช ื”ืžื ื’ื ื•ืŸ. ืืชื ืžื•ื–ืžื ื™ื ืœื”ืกืชื›ืœ ื‘ื’ื™ื˜ื”ืื‘ ื›ื“ื™ ืœืจืื•ืช ืืช ื”ืคืจื•ื™ืงื˜ ื”ืžืœื ื•ืืคื™ืœื• ืœื”ืจื™ืฅ ืื•ืชื•. ืื ืชื•ืจื™ื“ื• ืืœื™ื›ื ืืช ื”ืคืจื•ื™ืงื˜ ืื– ืื—ืจื™ ื”ืจืฆืช npm install ืชื•ื›ืœื• ืœื”ืคืขื™ืœ ืืฆืœื›ื ืืช ื”ืžืขืจื›ืช ื‘ื”ืื–ื ื” ืขืœ ืคื•ืจื˜ 5000 ืขื ื”ืคืงื•ื“ื”:
$ PORT=5000 node bin/www
ืื—ืจื™ ื”ื”ืคืขืœื” ืืคืฉืจ ืœื’ืœื•ืฉ ืœ http://localhost:5000/graphql ื•ืœืงื‘ืœ ืžืžืฉืง ื‘ื“ื™ืงื” ืฉืœ ื” API. ื‘ืžืžืฉืง ืื ื™ ื›ื•ืชื‘ ืฉืื™ืœืชื•ืช ื‘ืฆื“ ืฉืžืืœ ื•ืžืงื‘ืœ ืืช ื”ืชืฉื•ื‘ื•ืช ื‘ืฆื“ ื™ืžื™ืŸ. ืœื“ื•ื’ืžื” ื”ืฉืื™ืœืชื”:
query {
  tasks { 
    title
    description
    done
  }
}
ืชื—ื–ื™ืจ ืืช ื”ืชืฉื•ื‘ื”:
{
  "data": {
    "tasks": [
      {
        "title": "task1",
        "description": "write some code",
        "done": false
      },
      {
        "title": "task2",
        "description": "test it",
        "done": false
      },
      {
        "title": "task3",
        "description": "deploy",
        "done": false
      }
    ]
  }
}
ื‘ืฉื‘ื™ืœ ืœืกื™ื™ื ืžืฉื™ืžื” ืื ื™ ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘ืคื•ื ืงืฆื™ื” toggleTask ืฉื›ืชื‘ืชื™ ืขื ื”ืฉืื™ืœืชื” ื”ื‘ืื”:
mutation {
  toggleTask(id: 2) { 
    title
    done
  }
}
ื•ืœืงื‘ืœ ื‘ื—ื–ืจื”:
{
  "data": {
    "toggleTask": {
      "title": "task2",
      "done": true
    }
  }
}
ืฉื–ื” ืžืฆื‘ ื”ืขื ื™ื™ื ื™ื ื‘ืื•ื‘ื™ืงื˜ ืื—ืจื™ ื”ืฉื™ื ื•ื™. ื˜ื™ืค ืœืžื˜ื™ื‘ื™ ืœื›ืช: ื•ืื—ืจื™ ืฉื‘ื ื™ืชื ืืช ื” API, ืชื•ื›ืœื• ืœื—ื–ื•ืจ ืœืคื•ืกื˜ ื—ื™ื‘ื•ืจ ืืคืœื™ืงืฆื™ื™ืช ืจื™ืืงื˜ ืœ GraphQL ืฉื ืื ื™ ืžืกื‘ื™ืจ ืื™ืš ืœื—ื‘ืจ ืงื•ื“ ืจื™ืืงื˜ ืœืฉืจืช GraphQL ื‘ืขื–ืจืช ืกืคืจื™ื™ืช Relay.

ToCode
1 419
# ื‘ื•ืื• ื ื›ืชื•ื‘ ืฉืจืช GraphQL ื‘ Node.JS ื›ื“ื™ ืœืจืื•ืช ืื™ืš ื–ื” ืขื•ื‘ื“ ื’ืจืฃ ืงื™ื• ืืœ ื”ื•ื ื”ื“ื‘ืจ ื”ื’ื“ื•ืœ ื”ื‘ื ืžืื– ืฉื”ืžืฆื™ืื• ืืช ื”ืœื—ื ื”ื—ืชื•ืš. ื”ื•ื ืคื•ืชืจ ืืช ื›ืœ ื”ื‘ืขื™ื•ืช ืฉืœ REST ื•ืื– ืขื•ื“ ืงืฆืช ื•ื›ื‘ืจ ื›ืชื‘ืชื™ ืขืœื™ื• ืžืกืคืจ ืคื•ืกื˜ื™ื ื‘ืขื‘ืจ. ืื ืืชื ืœื ืžื›ื™ืจื™ื ืืช GraphQL ื‘ื›ืœืœ ืฉื•ื•ื” ืœื”ืชื—ื™ืœ ื‘ืžื‘ื•ื ืฉื›ืชื‘ืชื™ ื›ืืŸ: ืฉืœื•ื GraphQL. ื‘ืคื•ืกื˜ ื”ื™ื•ื ืื ื™ ืจื•ืฆื” ืœื›ืชื•ื‘ ืฉืจืช GraphQL ื‘ Node.JS ื• Express ื›ื“ื™ ืœืจืื•ืช ืื™ืš ื–ื” ืขื•ื‘ื“. ื”ืคืจื•ื™ืงื˜ ื”ื•ื API ืœืžืขืจื›ืช ื ื™ื”ื•ืœ ืžืฉื™ืžื•ืช ืฉืžืืคืฉืจ ืœื ื• ืœืจืื•ืช ืืช ื”ืžืฉื™ืžื•ืช ื”ืคืชื•ื—ื•ืช ื‘ืžืขืจื›ืช ื•ืœืขื“ื›ืŸ ืกื˜ื˜ื•ืก "ื‘ื•ืฆืข" ืฉืœ ื›ืœ ืžืฉื™ืžื”. ื”ืขืœื™ืชื™ ืืช ื›ืœ ื”ืงื•ื“ ื‘ืคื•ืกื˜ ืœืคืจื•ื™ืงื˜ ื“ื•ื’ืžื” ื‘ื’ื™ื˜ื”ืื‘ ื‘ืงื™ืฉื•ืจ: https://github.com/ynonp/express-graphql-demo ## ืฉื›ื‘ืช ื”ื ืชื•ื ื™ื ืžืืคื™ื™ืŸ ื—ืฉื•ื‘ ืฉืœ GraphQL ื”ื•ื ื”ื”ืคืจื“ื” ื‘ื™ืŸ ืฉื›ื‘ืช ื”ื ืชื•ื ื™ื ืœืฉื›ื‘ืช ื”ืชืงืฉื•ืจืช. ื™ืฉ ืœื ื• ื‘ืฆื“ ืื—ื“ ืืช ื”ืงื•ื“ ืฉื™ื•ื“ืข ืœืฉืœื•ืฃ ืžื‘ืกื™ืก ื”ื ืชื•ื ื™ื ื•ืœืขื“ื›ืŸ ืฉื ืืช ื”ืžื™ื“ืข, ื•ืงื•ื“ ื–ื” ื™ื›ื•ืœ ืœื”ื™ื•ืช ื›ืชื•ื‘ ื‘ื›ืœ ืกืคืจื™ื” ืฉืชืจืฆื• ืœื“ื•ื’ืžื” Mongo, Mongoose, Sequelize ืื• ื›ืžื• ืฉืื ื™ ืื›ืชื•ื‘ ื‘ื“ื•ื’ืžื” ื”ื™ื•ื ื‘ knex.js. ืื—ืจื™ื• ื™ืฉ ืœื ื• ืฉื›ื‘ืช ื—ื™ื‘ื•ืจ ืฉื ืงืจืืช Resolver ืื• Root Value. ืฉื›ื‘ืช ื”ื—ื™ื‘ื•ืจ ืื—ืจืื™ืช ืขืœ ืžื™ืคื•ื™ ื”ืขืจื›ื™ื ืžื”ืฉืื™ืœืชื” ืฉืžืฉืชืžืฉ ืฉืœื— ืœืคื•ื ืงืฆื™ื•ืช ื”ื’ื™ืฉื” ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื. ื•ื‘ืกื•ืฃ ื™ืฉ ืœื ื• ืืช ื”ืกื›ื™ืžื” ืฉืžืชืืจืช ื”ื—ื•ืฆื” ืื™ื–ื” ืžื™ื“ืข ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืกืคืง. ื”ื”ืคืจื“ื” ื‘ื™ืŸ ื”ืฉื›ื‘ื•ืช ืชืืคืฉืจ ืœื ื• ื‘ืขืชื™ื“ ืœืฉื ื•ืช ื‘ืงืœื•ืช ืืช ืฉื™ื›ื‘ืช ื”ื ืชื•ื ื™ื ืฉืœื ื• ื•ืืคื™ืœื• ืœื”ื—ืœื™ืฃ ื‘ืกื™ืก ื ืชื•ื ื™ื ืœื—ืœื•ื˜ื™ืŸ ื•ืขื“ื™ื™ืŸ ืœื”ืฉืื™ืจ ืืช ื”ืžืžืฉืง ื”ื—ื•ืฆื” ืœืœืงื•ื—ื•ืช ืœืœื ืฉื™ื ื•ื™. ืžืกื™ื‘ื” ื–ื• ืื ื—ื ื• ืžืื•ื“ ืื•ื”ื‘ื™ื ืœื”ืฉืชืžืฉ ื‘ GraphQL ื‘ืืจื›ื™ื˜ืงื˜ื•ืจืช Micro Services ื›ื“ื™ ืœื‘ื ื•ืช ืืช ื”ืชืงืฉื•ืจืช ื‘ื™ืŸ ื”ืกืจื‘ื™ืกื™ื ื”ืฉื•ื ื™ื ื‘ืฆื•ืจื” ื™ืฆื™ื‘ื”. ื ืชื—ื™ืœ ื‘ื‘ื ื™ื™ืช ืฉื›ื‘ืช ื”ื ืชื•ื ื™ื ื•ื‘ืคืจื•ื™ืงื˜ ื”ื“ื•ื’ืžื” ื‘ื—ืจืชื™ ื‘ knex.js. ื”ืงื•ื“ ืฉืื—ืจืื™ ืขืœ ื”ืฉืื™ืœืชื•ืช ื”ื•ื ื‘ืกืš ื”ื›ืœ ืงื•ื‘ืฅ ืงืฆืจ ืฉืœ ืคื—ื•ืช ืž 20 ืฉื•ืจื•ืช:
// dl/tasks.js
const knex = require('../db/knex');

exports.getTasks = function getTasks() {
  return knex.from('tasks').select('*');
}

exports.getTask = function getTask(id) {
  return knex.from('tasks').where({ id: id }).first('*');
}

exports.getTasksBy = function getTasksBy(attributes) {
  return knex.from('tasks').where(attributes).select('*');
}

exports.toggleTask = function toggleTask(id) {
  return knex('tasks')
  .where({ id })
  .update({ done: knex.raw("CASE WHEN done = 0 THEN 1 ELSE 0 END") });
}
ื”ืžื™ืžื•ืฉ ืฉืœ ื”ืคื•ื ืงืฆื™ื•ืช ื”ืกืคืฆื™ืคื™ื•ืช ืคื—ื•ืช ื—ืฉื•ื‘ ื‘ืฉื‘ื™ืœ ื”ื“ื•ื’ืžื” ืฉืœื ื•. ืฉื™ืžื•ืฉ ื‘ื‘ืกื™ืก ื ืชื•ื ื™ื ืื—ืจ ืื• ื‘ืกืคืจื™ื™ืช ื’ื™ืฉื” ืื—ืจืช ืœื‘ืกื™ืก ื”ื ืชื•ื ื™ื ื”ื™ื• ืžื™ื™ืฆืจื™ื ืžื™ืžื•ืฉื™ื ืื—ืจื™ื, ืื‘ืœ ื–ื” ื‘ืกื“ืจ ื’ืžื•ืจ. ื›ืœ ืขื•ื“ ืฉืžื•ืช ื”ืคื•ื ืงืฆื™ื•ืช ื•ื”ืคืจืžื˜ืจื™ื ื–ื”ื™ื ื›ืœ ืฉืืจ ื”ืงื•ื“ ืœื ื™ืฉืชื ื”. ## ื”ืกื›ื™ืžื” ื ืขื‘ื•ืจ ืœืฆื“ ื”ืฉื ื™ ืฉืœ ื”ืขื•ืœื ื‘ืฉื‘ื™ืœ ืœื“ื‘ืจ ืขืœ ื”ืกื›ื™ืžื”. ืกื›ื™ืžื” ื‘ GraphQL ื”ื™ื ืคืฉื•ื˜ ืชื™ืื•ืจ ืฉืœ ื”ืื•ื‘ื™ืงื˜ื™ื, ื”ืžืืคื™ื™ื ื™ื ืฉืœื”ื ื•ืื ื™ืฉ ืœื”ื ืื•ื‘ื™ืงื˜ื™ื ืžืงื•ื ื ื™ื ืื– ื’ื ืชื™ืื•ืจ ืฉืœ ืื•ืชื ืฉื“ื•ืช ืคื ื™ืžื™ื™ื. ื”ืกื›ื™ืžื” ืžืชืืจืช ื’ืจืฃ ื•ื™ื›ื•ืœื” ืœื”ืชืื™ื ืœืžืฉืคื˜ื™ื ื›ืžื•: 1. ืœื›ืœ ืžืฉื™ืžื” ื™ืฉ ืฉื“ื” "ืกื˜ื˜ื•ืก" ืžืกื•ื’ ื‘ื•ืœื™ืื ื™ ื•ืฉื“ื” "ืชื™ืื•ืจ" ืžืกื•ื’ ื˜ืงืกื˜ 2. ืœื›ืœ ืžืฉืชืžืฉ ื‘ืžืขืจื›ืช ื™ืฉ ืฉื“ื” "ืฉื" ืขื ื”ืฉื ืฉืœื• 3. ืœื›ืœ ืžืฉืชืžืฉ ื‘ืžืขืจื›ืช ื™ืฉ 1 ืื• ื™ื•ืชืจ ืžืฉื™ืžื•ืช 4. ืœื›ืœ ืžืฉื™ืžื” ื™ืฉ 1 ืื• ื™ื•ืชืจ ืชื’ื™ื•ืช ื—ื™ืฉื‘ื• ืขืœ ื”ืกื›ื™ืžื” ื‘ื“ื™ื•ืง ื›ืžื• ืขืœ ืกื›ื™ืžื” ืฉืœ ื‘ืกื™ืก ื ืชื•ื ื™ื, ืจืง ื‘ืœื™ ืœื“ื‘ืจ ืขืœ ื‘ืกื™ืก ื”ื ืชื•ื ื™ื ืฉืžืื—ื•ืจื™ื”. ืœ GraphQL ื™ืฉ ืฉืคื” ืžืขื ื™ื™ื ืช ืœื›ืชื™ื‘ืช ืกื›ื™ืžื•ืช ื•ืืคืฉืจ ืœืงืจื•ื ืขืœื™ื” ื›ืืŸ. ื”ื ื” ื”ืกื›ื™ืžื” ื”ืžืื•ื“ ืคืฉื•ื˜ื” ืฉืื ื™ ื›ืชื‘ืชื™ ืœืชื™ืื•ืจ ื”ืžืฉื™ืžื•ืช ื•ื”ื“ื‘ืจื™ื ืฉืื ื—ื ื• ื™ื›ื•ืœื™ื ืœืขืฉื•ืช ืขื ืื•ืชืŸ ืžืฉื™ืžื•ืช:
  type Query {
    tasks: [Task],
    task(id: Int!): Task
  }

  type Task {
    title: String,
    description: String,
    done: Boolean,
  }

  type Mutation {
    toggleTask(id: Int!): Task
  }
ื”ืกื›ื™ืžื” ืžื•ืจื›ื‘ืช ืž-3 ื˜ื™ืคื•ืกื™ื: 1. ื”ื˜ื™ืคื•ืก ื”ืžื™ื•ื—ื“ Query (ื”ื•ื ืžื™ื•ื—ื“ ื‘ื’ืœืœ ื”ืฉื, Query ื–ื” ืฉื ืฉืžื•ืจ ื‘ GraphQL) ื›ื•ืœืœ ืฉื“ื” ื‘ืฉื tasks ืฉืฆืจื™ืš ืœื”ื—ื–ื™ืจ ืจืฉื™ืžืช ืžืฉื™ืžื•ืช, ื•ืฉื“ื” ื‘ืฉื task ืฉืžืงื‘ืœ id ืžืกื•ื’ ืžืกืคืจ ื•ืžื—ื–ื™ืจ ืžืฉื™ืžื” ื‘ื•ื“ื“ืช. ื•ื›ืฉืื ื™ ื›ื•ืชื‘ "ืฉื“ื”" ืชื—ืฉื‘ื• ื‘ืœื‘ "ืคื•ื ืงืฆื™ื”", ื›ื™ ื–ื” ืžื” ืฉื‘ืืžืช ื™ืฉื‘ ื‘ืฉื“ื•ืช ื”ืืœื”. 2. ื”ื˜ื™ืคื•ืก ื”ืžื™ื•ื—ื“ Mutation (ืฉื•ื‘ ืžื™ื•ื—ื“ ื‘ื’ืœืœ ื”ืฉื, Mutation ื”ื•ื ืฉื ืฉืžื•ืจ ื‘ GraphQL) ื›ื•ืœืœ ืฉื“ื” ื™ื—ื™ื“ ื‘ืฉื toggleTask. ืฉื“ื” ื›ื–ื›ื•ืจ ื”ื•ื ืคื•ื ืงืฆื™ื” ื•ื”ืคื•ื ืงืฆื™ื” ื›ืืŸ ืžืงื‘ืœืช ืžื–ื”ื” ื•ืžื—ื–ื™ืจื” ืžืฉื™ืžื”. 3. ื”ื˜ื™ืคื•ืก Task ืžืชืืจ ืžื”ื™ ืžืฉื™ืžื”. ื”ื•ื ืžืกืคืจ ืœื ื• ืฉืœืžืฉื™ืžื” ื™ืฉ ืฉืœื•ืฉื” ืฉื“ื•ืช: title, description ื• done ื•ืืช ื”ืกื•ื’ื™ื ืฉืœื”ื. ื‘ืฉื‘ื™ืœ ืœื‘ื ื•ืช ืื•ื‘ื™ืงื˜ ืกื›ื™ืžื” ืฉืœ GraphQL ืื ื™ ืžืขื‘ื™ืจ ืืช ื”ืชื™ืื•ืจ ื”ื˜ืงืกื˜ื•ืืœื™ ื”ื–ื” ืœืคื•ื ืงืฆื™ื” ื‘ืฉื buildSchema. ## ื” Resolver

ToCode
1 419
/daily

ToCode
1 419
            stream: Stream[Message, Empty]
            ) -> None:
        request = await stream.recv_message()
        for q in self.chatters.values():
            q.put_nowait(request.text)
        await stream.send_message(Empty())


async def main(*, host: str = '127.0.0.1', port: int = 50051) -> None:
    server = Server([ChatRoom()])
    with graceful_exit([server]):
        await server.start(host, port)
        print(f'Serving on {host}:{port}')
        await server.wait_closed()


if __name__ == '__main__':
    asyncio.run(main())
ื‘ืฆื“ ื”ืœืงื•ื— ื”ืืชื’ืจ ื”ื•ื ืœื‘ืฆืข ืฉืชื™ ืžืฉื™ืžื•ืช ื‘ืžืงื‘ื™ืœ: ืื ื™ ื’ื ืฆืจื™ืš ืœื”ืชื—ื‘ืจ ืœืฉืจืช ื•ืœื”ื“ืคื™ืก ื›ืœ ื”ื•ื“ืขื” ืฉื—ื•ื–ืจืช ืž Subscribe, ื•ื’ื ืฆืจื™ืš ืœื”ืงืฉื™ื‘ ืœืฉื•ืจื•ืช ืฉืžืฉืชืžืฉ ืžืงืœื™ื“ ื‘ stdin ื•ื›ืœ ืคืขื ืฉืžืฉืชืžืฉ ืžืกื™ื™ื ืœื›ืชื•ื‘ ืฉื•ืจื” ืœืฉืœื•ื— ืื•ืชื” ืœืฉืจืช. ื”ืงืกื ืฉืขื•ืฉื” ืืช ืฉื ื™ ื”ื“ื‘ืจื™ื ื‘ืžืงื‘ื™ืœ ื”ื•ื ื”ืคื•ื ืงืฆื™ื” wait:
async def main() -> None:
    await asyncio.wait([
        asyncio.create_task(chat()),
        asyncio.create_task(read_messages_and_send()),
        ])
ื–ื• ืคื•ื ืงืฆื™ื” ืฉืžืงื‘ืœืช ืžืกืคืจ ืคื•ื ืงืฆื™ื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช ื•ืžืจื™ืฆื” ืืช ื›ื•ืœืŸ ื‘ืžืงื‘ื™ืœ. ืืฆืœื™ ื”ืคื•ื ืงืฆื™ื” chat ื”ื™ื ื–ื• ืฉืžื“ืคื™ืกื” ืืช ื”ื”ื•ื“ืขื•ืช ืžื”ืฉืจืช ื•ื”ืคื•ื ืงืฆื™ื” read_messages_and_send ืงื•ืจืืช ื”ื•ื“ืขื•ืช ืžื”ืžืงืœื“ืช ื•ืฉื•ืœื—ืช ืื•ืชืŸ ืœืฉืจืช. ืงื•ื“ ื”ืชื•ื›ื ื™ืช ื”ืžืœื ื‘ืงื•ื‘ืฅ client.py ื ืจืื” ื›ืš:
# File: chat_client.py

import asyncio
import sys

from grpclib.client import Channel

from chat_grpc import ChatRoomStub
from chat_pb2 import Message, Empty

async def connect_stdin_stdout():
    loop = asyncio.get_event_loop()
    reader = asyncio.StreamReader()
    protocol = asyncio.StreamReaderProtocol(reader)
    await loop.connect_read_pipe(lambda: protocol, sys.stdin)
    w_transport, w_protocol = await loop.connect_write_pipe(asyncio.streams.FlowControlMixin, sys.stdout)
    writer = asyncio.StreamWriter(w_transport, w_protocol, reader, loop)
    return reader, writer


async def chat() -> None:
    async with Channel('127.0.0.1', '50051') as channel:
        stub = ChatRoomStub(channel)
        
        async with stub.Subscribe.open() as stream:
            await stream.send_message(Empty(), end=True)
            async for reply in stream:
                print(reply)

async def read_messages_and_send() -> None:
    reader, writer = await connect_stdin_stdout()
    async with Channel('127.0.0.1', '50051') as channel:
        stub = ChatRoomStub(channel)
        while True:
            res = await reader.read(100)
            if not res:
                break
            await stub.SendMessage(Message(text=res))


async def main() -> None:
    await asyncio.wait([
        asyncio.create_task(chat()),
        asyncio.create_task(read_messages_and_send()),
        ])



if __name__ == '__main__':
    asyncio.run(main())
ืžื•ื–ืžื ื™ื ืœื ืกื•ืช ืœื”ืจื™ืฅ ืืฆืœื›ื ื‘ื—ืœื•ืŸ ืื—ื“ ืืช ื”ืฉืจืช ื•ื‘ืžืกืคืจ ื—ืœื•ื ื•ืช ืื—ืจื™ื ืืช ืชื•ื›ื ื™ืช ื”ืœืงื•ื— ื•ืœืจืื•ืช ืื™ืš ื”ื—ืœื•ื ื•ืช ืžื“ื‘ืจื™ื ืื—ื“ ืขื ื”ืฉื ื™. ## ืžื” ืื”ื‘ืชื™ ืกืš ื”ื›ืœ gRPC ื”ื™ื ืกืคืจื™ื” ื ื—ืžื“ื” ืœื—ื™ื‘ื•ืจ ื‘ื™ืŸ ืžืกืคืจ ืกืจื‘ื™ืกื™ื. ื”ืขื•ื‘ื“ื” ืฉื™ืฉ ืœื” ืชืžื™ื›ื” ื‘ืื™ื ืกื•ืฃ ืฉืคื•ืช ืชื›ื ื•ืช ืื•ืžืจืช ืฉื™ื”ื™ื” ืœื ื• ืงืœ ืœื—ื‘ืจ ืงื•ื“ ืฉื›ืชื•ื‘ ื‘ืฉืคื•ืช ืฉื•ื ื•ืช, ื•ืงื•ื‘ืฅ ื” proto ื ื•ืชืŸ ืœื™ ื“ืจืš ืกื˜ื ื“ืจื˜ื™ืช ืœื”ื’ื“ื™ืจ ืžืžืฉืง ืขื‘ื•ืจ ื”ืกืจื‘ื™ืก ืฉืœื™. ## ืžื” ืœื ืื”ื‘ืชื™ ืœืžืจื•ืช ืฉืื ื—ื ื• ื‘ 2021, ื”ืกืคืจื™ื” ืžืจื’ื™ืฉื” ืงืฆืช ื›ืžื• ื—ื–ืจื” ื‘ื–ืžืŸ. ื‘ืขื™ืงืจ ื”ื™ืชื” ื—ืกืจื” ืœื™ ืชืžื™ื›ื” ืžื•ื‘ื ื™ืช ื‘ื ื™ื”ื•ืœ ื”ืจืฉืื•ืช (ื›ืŸ ืจืื™ืชื™ ืฉื™ืฉ ืžืฉื”ื• ืžื•ื‘ื ื” ืฉืœ ื’ื•ื’ืœ ื•ืืคืฉืจื•ืช ืœื”ื•ืกื™ืฃ ืคืœืื’ื™ื ื™ื. ื–ื” ืœื ื ืจืื” ื ื•ื—), ื•ื›ืžื• ื‘ REST, ื’ื ื›ืืŸ ื”ืžืžืฉืง ืžืื•ื“ ืงืฉื™ื—. ื›ืœ ืฉื™ื ื•ื™ ืงื˜ืŸ ื‘ืžื™ื“ืข ืžื—ื™ื™ื‘ ืฉื™ื ื•ื™ ืฉืœ ื”ืคืจื•ื˜ื•ืงื•ืœ ื•ืชื™ืื•ื ื‘ื™ืŸ ืžืกืคืจ ืกืจื‘ื™ืกื™ื. ื”ื‘ื—ื™ืจื” ื‘ gRPC ื”ื™ื ื‘ื—ื™ืจื” ื‘ื‘ื™ืฆื•ืขื™ื ืขืœ ื—ืฉื‘ื•ืŸ ื’ืžื™ืฉื•ืช. ื›ืฉืืชื ื‘ืกื™ื˜ื•ืืฆื™ื” ืฉื”ื‘ื™ืฆื•ืขื™ื ืงืจื™ื˜ื™ื™ื ื•ืฆืจื™ื›ื™ื ืœื”ืขื‘ื™ืจ ื”ืจื‘ื” ืžื™ื“ืข ื•ืžื”ืจ ื™ื›ื•ืœ ืœื”ื™ื•ืช ืฉ gRPC ื™ื”ื™ื” ืคื™ืชืจื•ืŸ ื˜ื•ื‘. ื‘ืจื•ื‘ ื”ืกื™ื˜ื•ืืฆื™ื•ืช GraphQL ื™ื™ืชืŸ ืชื•ืฆืื” ื™ื•ืชืจ ื˜ื•ื‘ื” ื‘ื’ืœืœ ื ื•ื—ื•ืช ื”ืขื‘ื•ื“ื” ื•ื”ื’ืžื™ืฉื•ืช ืฉืœ ื”ืคืจื•ื˜ื•ืงื•ืœ.

ToCode
1 419
        await stream.send_message(HelloReply(message=message))


async def main(*, host='127.0.0.1', port=50051):
    server = Server([Greeter()])
    # Note: graceful_exit isn't supported in Windows
    with graceful_exit([server]):
        await server.start(host, port)
        print(f'Serving on {host}:{port}')
        await server.wait_closed()


if __name__ == '__main__':
    asyncio.run(main())
ื‘ืฆื“ ื”ืœืงื•ื— ืื ื™ ืžื•ืฉืš ื“ื‘ืจ ืฉื ืงืจื Stub ืžืชื•ืš ืื•ืชื• ืงื•ื‘ืฅ grpc ืฉื ื•ืฆืจ ืื•ื˜ื•ืžื˜ื™ืช, ื•ื‘ืขื–ืจืชื• ืžืคืขื™ืœ ืคื•ื ืงืฆื™ื” ืžืจื•ื—ืงืช. ื”ืคืขื ื”ืงื•ื“ ื ืจืื” ื”ืจื‘ื” ื™ื•ืชืจ ื˜ื‘ืขื™ ืœืคื™ื™ืชื•ืŸ ื•ื›ื‘ืจ ืœื ืžืจื’ื™ืฉื™ื ืืช ื”ืขื‘ื•ื“ื” ื”ืžื‘ื•ื–ืจืช:
reply = await greeter.SayHello(HelloRequest(text=line.strip()))
ื•ื–ื” ืงื•ื“ ืฆื“ ื”ืœืงื•ื— ื”ืžืœื:
# File: client.py

import asyncio

from grpclib.client import Channel

# generated by protoc
from sayhello_pb2 import HelloRequest, HelloReply
from sayhello_grpc import GreeterStub
import sys

async def main():
    async with Channel('127.0.0.1', 50051) as channel:
        greeter = GreeterStub(channel)

        for line in sys.stdin:
            reply = await greeter.SayHello(HelloRequest(text=line.strip()))
            print(reply.message)


if __name__ == '__main__':
    asyncio.run(main())
ืื ื™ ืฉืžืจืชื™ ืืช ืงื•ื“ ืฆื“ ื”ืฉืจืช ื‘ืงื•ื‘ืฅ server.py ื•ืืช ืงื•ื“ ืฆื“ ื”ืœืงื•ื— ื‘ืงื•ื‘ืฅ client.py ื•ืื– ืืคืฉืจ ืžืฉื ื™ ื—ืœื•ื ื•ืช ืฉื•ื ื™ื ืœื”ืคืขื™ืœ ืืช ื”ืฉืจืช ื•ื”ืœืงื•ื—, ืœื›ืชื•ื‘ ืžืฉื”ื• ื‘ืžืกื•ืฃ ื‘ืฆื“ ื”ืœืงื•ื— ื•ืœืจืื•ืช ืืช ื”ื”ื“ืคืกื” ืฉื—ื•ื–ืจืช ืžื”ืฉืจืช. ## ืชื•ื›ื ื™ืช ืฉื ื™ื”: ืฉืจืช Chat ื ืžืฉื™ืš ืœืžืฉื”ื• ืงืฆืช ื™ื•ืชืจ ืžืชื•ื—ื›ื ื•ื”ื•ื ืชื•ื›ื ื™ืช ืฆ'ื˜. ื‘ื ื™ื’ื•ื“ ืœืฉืจืช Echo ืฉื‘ืกืš ื”ื›ืœ ืฉื•ืœื— ืœืš ื‘ื—ื–ืจื” ืืช ืžื” ืฉื›ืชื‘ืช, ืชื•ื›ื ื™ืช ืฆ'ื˜ ืฆืจื™ื›ื” ืœื”ื›ื™ืจ ืืช ื›ืœ ื”ืœืงื•ื—ื•ืช ื”ืžื—ื•ื‘ืจื™ื ื•ื›ืœ ืคืขื ืฉืื—ื“ ืžื”ื ืฉื•ืœื— ื”ื•ื“ืขื” ื”ื™ื ืฆืจื™ื›ื” ืœื”ื•ื“ื™ืข ืœื›ืœ ื”ืœืงื•ื—ื•ืช ื”ืื—ืจื™ื. ื™ืฉ ืคื” ืฉื ื™ ืืชื’ืจื™ื ื—ื“ืฉื™ื ื’ื ื‘ืฆื“ ื”ืฉืจืช ื•ื’ื ื‘ืฆื“ ื”ืœืงื•ื—: 1. ื‘ืฆื“ ื”ืœืงื•ื— ืื ื™ ื›ื‘ืจ ืœื ื™ื•ื“ืข ืžืชื™ ืื ื™ ืืงื‘ืœ ืืช ื”ื”ื•ื“ืขื” ื”ื‘ืื”. ืื ื™ ืœื ื™ื›ื•ืœ ืœืกืžื•ืš ืขืœ ื–ื” ืฉื”ื•ื“ืขื” ืชื’ื™ืข ืจืง ื‘ืชื•ืจ ืชืฉื•ื‘ื” ืœื”ื•ื“ืขื” ืฉืื ื™ ืฉื•ืœื—, ื›ื™ ื™ืฉ ืื ืฉื™ื ืื—ืจื™ื ื‘ื—ื“ืจ ืฉืฉื•ืœื—ื™ื ื•ืžืงื‘ืœื™ื ื”ื•ื“ืขื•ืช ื›ืœ ื”ื–ืžืŸ. 2. ื‘ืฆื“ ื”ืฉืจืช ืื ื™ ื›ื‘ืจ ืœื ื™ื›ื•ืœ ืœืฉืœื•ื— ื”ื•ื“ืขื” ื—ื–ืจื” ืจืง ืœืžื™ ืฉื”ืจื’ืข ืคื ื” ืืœื™ื™, ื•ืฆืจื™ืš ืœืฉืžื•ืจ ืืช ื›ืœ ื”ืœืงื•ื—ื•ืช ื”ืžื—ื•ื‘ืจื™ื ื‘ื–ื™ื›ืจื•ืŸ ื›ื“ื™ ืฉื›ืœ ืคืขื ืฉืื—ื“ ืฉื•ืœื— ื”ื•ื“ืขื” ืื•ื›ืœ ืœื”ื—ื–ื™ืจ ืืช ื”ื”ื•ื“ืขื” ื’ื ืœื›ืœ ื”ืื—ืจื™ื. ื ืชื—ื™ืœ ืขื ื”ืคืจื•ื˜ื•ืงื•ืœ. ื‘ื’ืœืœ ืฉื–ื” ื‘ืกืš ื”ื›ืœ ืžืฉื—ืง ืขื gRPC ืžืกืคื™ืงื•ืช ืœื™ ืฉืชื™ ืคื•ื ืงืฆื™ื•ืช:
syntax = "proto3";

service ChatRoom {
  rpc Subscribe (Empty) returns (stream Message) {}
  rpc SendMessage (Message) returns (Empty) {}
}

message Message {
  string text = 1;
}

message Empty {}
ืœืงื•ื— ื™ืงืจื ืœืคื•ื ืงืฆื™ื” Subscribe ื•ื”ืชืฉื•ื‘ื” ืฉื”ื•ื ื™ืงื‘ืœ ืชื”ื™ื” stream ืฉืœ ื”ื•ื“ืขื•ืช. ื‘ gRPC, ื”ืžื™ืœื” stream ืื•ืžืจืช ืฉืื ื™ ื™ื›ื•ืœ ืœืฉืœื•ื— ื™ื•ืชืจ ืžืชืฉื•ื‘ื” ืื—ืช. ื‘ืžืงื‘ื™ืœ ืœืงื•ื—ื•ืช ืื—ืจื™ื ืื• ืื•ืชื• ืœืงื•ื— ื™ื›ื•ืœื™ื ืœืงืจื•ื ืœืคื•ื ืงืฆื™ื” SendMessage ื›ื“ื™ ืœืฉืœื•ื— ื”ื•ื“ืขื•ืช. ื›ืฉืžื™ืฉื”ื• ืงื•ืจื ืœ SendMessage ืื– ื›ืœ ืืœื” ืฉืขื›ืฉื™ื• ืชืงื•ืขื™ื ืขืœ Subscribe ืžืงื‘ืœื™ื ืืช ื”ื”ื•ื“ืขื” ื”ื—ื“ืฉื”, ื‘ืœื™ ืœืกื™ื™ื ืืช ื”ืชืงืฉื•ืจืช. ื ืžืฉื™ืš ืขื ืงื•ื“ ืฆื“ ื”ืฉืจืช. ื‘ืฆื“ ื”ืฉืจืช ืื ื™ ืฉื•ืžืจ ื‘ืžื—ืœืงื” ืžื‘ื ื” ื ืชื•ื ื™ื ืฉืœ ืžื™ืœื•ืŸ ืฉืžื—ื–ื™ืง ืืช ื›ืœ ื”ืœืงื•ื—ื•ืช ื”ืžื—ื•ื‘ืจื™ื. ื”ืžืคืชื— ื”ื•ื ื›ืชื•ื‘ืช ื”ืœืงื•ื— ื•ื”ืขืจืš ื”ื•ื ืชื•ืจ ื”ื•ื“ืขื•ืช ืฉื™ืฉ ืœื™ ืขื‘ื•ืจ ืื•ืชื• ืœืงื•ื—. ื›ืœ ืคืขื ืฉืœืงื•ื— ื—ื“ืฉ ืžืชื—ื‘ืจ ืื ื™ ื™ื•ืฆืจ ืขื‘ื•ืจื• ืฉื•ืจื” ื—ื“ืฉื” ื‘ืžื™ืœื•ืŸ ื•ื ื›ื ืก ืœืœื•ืœืื” ืฉื‘ื” ื›ืœ ืคืขื ืฉื™ืฉ ื”ื•ื“ืขื” ื—ื“ืฉื” ืื ื™ ืฉื•ืœื— ืื•ืชื”. ื–ื” ื”ืชืคืงื™ื“ ืฉืœ ื”ืคื•ื ืงืฆื™ื” Subscribe. ื”ืคื•ื ืงืฆื™ื” ื”ืฉื ื™ื”, SendMessage ืคืฉื•ื˜ ืžื•ืกื™ืคื” ืืช ื”ื”ื•ื“ืขื” ืœืชื•ืจ ืฉืœ ื›ืœ ื”ืœืงื•ื—ื•ืช ื”ืžื—ื•ื‘ืจื™ื. ืงื•ื“ ืฆื“ ื”ืฉืจืช ื”ืžืœื ื ืจืื” ื›ืš:
# File: chat_server.py

import asyncio

from grpclib.server import Server, Stream
from grpclib.utils import graceful_exit

from chat_grpc import ChatRoomBase
from chat_pb2 import Message, Empty

class ChatRoom(ChatRoomBase):
    def __init__(self):
        self.chatters = {}

    async def Subscribe(
            self,
            stream: Stream[Empty, Message]
            ) -> None:

        peer = stream.peer.addr()
        try:
            self.chatters[peer] = asyncio.Queue()
            request = await stream.recv_message()
            
            while True:
                message = await self.chatters[peer].get()
                await stream.send_message(Message(text=message))
                self.chatters[peer].task_done()
        finally:
            print(f"Bye bye {peer}")
            del(self.chatters[peer])

    async def SendMessage(
            self,