雲計算

小程序雲的進階開發技巧

雲數據庫

雲數據庫(數據存儲服務)是基於MongoDB託管在雲端的數據庫,數據以JSON格式存儲。作為開發者,您可以在客戶端內直接操作數據,也可以在雲函數中讀寫數據。

數據庫常用語法說明

數據存儲服務是基於MongoDB託管在雲端的數據庫,使用MongoDB 3.4版本,常用的數據庫操作語法如下。

聚合查詢aggregate
計算記錄條數count
刪除一條數據記錄deleteOne
刪除一批數據記錄deleteMany
獲取去重後的記錄distinct
查詢記錄find
查詢單條記錄findOne
查詢並刪除一條記錄findOneAndDelete
查詢並替換一條記錄findOneAndReplace
查詢並更新記錄findOneAndUpdate
替換記錄replaceOne
添加一批記錄insertMany
添加一條記錄insertOne
更新一批記錄updateMany
更新一條記錄updateOne

使用地理位置數據

小程序雲支持以下幾種地理位置數據類型:

  • Point,點
{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }
  • LineString,線
{ type: "LineString", coordinates: [ [ 40, 5 ], [ 41, 6 ] ] }
  • Polygon,多邊形
{
  type: "Polygon",
  coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0  ] ] ]
}
  • MultiPoint, 點集合
{
  type: "MultiPoint",
  coordinates: [
     [ -73.9580, 40.8003 ],
     [ -73.9498, 40.7968 ],
     [ -73.9737, 40.7648 ],
     [ -73.9814, 40.7681 ]
  ]
}
  • MultiLineString,線段集合
{
  type: "MultiLineString",
  coordinates: [
     [ [ -73.96943, 40.78519 ], [ -73.96082, 40.78095 ] ],
     [ [ -73.96415, 40.79229 ], [ -73.95544, 40.78854 ] ],
     [ [ -73.97162, 40.78205 ], [ -73.96374, 40.77715 ] ],
     [ [ -73.97880, 40.77247 ], [ -73.97036, 40.76811 ] ]
  ]
}
  • MultiPolygon,多邊形集合
{
  type: "MultiPolygon",
  coordinates: [
     [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.9814, 40.7681 ], [ -73.958, 40.8003 ] ] ],
     [ [ [ -73.958, 40.8003 ], [ -73.9498, 40.7968 ], [ -73.9737, 40.7648 ], [ -73.958, 40.8003 ] ] ]
  ]
}

插入地理位置數據示例:

// 在小程序端  
my.serverless.db.collection('places').insertMany([
        {
          location: { type: "Point", coordinates: [-73.88, 40.78] },
          name: "La Guardia Airport",
          category: "Airport"
        },
        {
          location: { type: "LineString", coordinates: [[113, 23], [120, 50]] },
          name: "ss Airport",
          category: "Airport"
        }
  ]}
  // 在雲函數中插入
 ctx.mpserverless.db.collection('places').insertMany([
        {
          location: { type: "Point", coordinates: [-73.88, 40.78] },
          name: "La Guardia Airport",
          category: "Airport"
        },
        {
          location: { type: "LineString", coordinates: [[113, 23], [120, 50]] },
          name: "ss Airport",
          category: "Airport"
        }
  ]}                                                

創建地理位置索引

可以通過控制檯或者調用RunDBComand接口來創建地理位置類型的索引。以下為使用RunDBComand接口創建地理位置索引的Body參數示例。

{
    "command": "createIndex",
    "collection": "places",
    "field": {
        "location": "2dsphere"
    },
    "options": {
        "name": "location_2dsphere",
        "unique": false
    }
}

查詢地理位置數據

您可以在小程序端或者雲函數中來使用地理位置查詢,兩者的查詢語法是相同的。支持以下幾種查詢方法:

  • nearSphere

     • 按從近到遠的順序,找出字段值在給定地點附近的記錄。
    
// 使用nearSphere必須給查詢的字段添加地理位置索引,否則會查詢失敗。
my.serverless.db.collection('places').find(
  {
    location: {
      $nearSphere: {
        $geometry: {
          type: "Point",
          coordinates: [-73.9667, 40.78]
        },
        $minDistance: 1000,
        $maxDistance: 5000
      }
    }
  }
);
  • geoWithin

     • 找出字段值在給定區域內的記錄。給定區域可以是Polygon、MultiPolygon或者CenterSphere。
    
my.serverless.db.collection('places').find(
  {
    location: {
      $geoWithin: {
        $geometry: {
          type: "Polygon",
          coordinates: [
            [[0, 0], [30, 20], [20, 30], [0, 0]],
            [[10, 10], [16, 14], [14, 16], [10, 10]]
          ]
        }
      }
    }
  }
);
  • geoNear(聚合查詢)

     • 適用於聚合階段,將記錄按照給定點從近到遠輸出。
    
my.serverless.db.collection('places').aggregate(
  [
    {
      $geoNear: {
        near: { type: "Point", coordinates: [113.323809, 23.097732] },
        distanceField: "distance",
        maxDistance: 2,
        query: { category: "Parks" },
        includeLocs: "location",
        spherical: true
      }
    }
  ]
);

設置數據庫索引

使用數據庫時,對成為查詢條件的字段設置索引可以有效提高查詢效率,更快的獲取信息。缺省情況下會
對_id_字段默認創建一個非唯一索引。

1.在數據庫頁面,單擊目標數據表,然後單擊索引頁籤進入索引設置頁面。
2.點擊添加索引進入索引設置頁面。
3.填寫索引名稱,設置索引屬性、索引字段。

  • 索引屬性:可以設置為唯一索引或非唯一索引。

將字段設置為唯一索引後,可以防止不同記錄的被索引鍵上存儲相同值。

  • 索引字段:支持單鍵索引和複合索引設置,字段按升序或降序排列。

單鍵索引是最常見的索引形式,針對一個指定字段建立索引。對於單字段索引,升序、降序的查詢效果一樣。
複合索引是是單鍵索引的升級版,針對多個字段聯合創建索引,先按照第一個字段排列,第一個字段相同的記錄按第二個字段排列,依次類推。

4.單擊保存按鈕,保存索引設置。

image.png

image.png

雲函數

雲函數(FaaS)是一段運行在雲端的、輕量的、無關聯的、並且可重用的代碼。無需管理服務器,只需編寫和上傳代碼,即可獲得對應的數據結果。使用雲函數可以使企業和開發者不需要擔心服務器或底層運維設施,可以更專注代碼和業務本身,也可以使代碼進一步解耦,增加其重用性。

雲函數示例

雲函數目錄結構

在Serverless小程序工程的server/functions目錄下創建雲函數目錄,其中index.js是雲函數getImageList的入口文件。

└── server/
    └── functions
           └── getImageList
                   └── index.js

雲函數代碼結構

以下代碼示例展示瞭如何從數據庫images裡面查出特定用戶上傳的圖片記錄。雲函數裡可以直接通過API調用數據存儲,文件存儲的服務資源以及其他雲函數。

  • 當雲函數被客戶端或者其他雲函數調用時,可以通過ctx.args獲得調用傳來的參數。
  • 可以通過ctx.logger方法打印不同類型的日誌信息,然後在雲函數控制檯中查看執行日誌。
  • 在雲函數內通過ctx.env來獲取環境參數,例如SpaceId、調用來源、客戶端源IP和客戶端UserAgent等信息。ctx.env是一個object,它包含MP_SPACE_ID(SpaceId),MP_SOURCE(調用來源),MP_USER_AGENT(客戶端User-agent),MP_CLIENT_IP(客戶端IP)。
  • 在雲函數中,您可以直接調用同一環境(空間)的數據存儲和文件存儲服務以及獲取當前請求用戶的基本信息。ctx.mpserverless在雲函數封裝了小程序的基礎服務, API使用方式和客戶端一致。

     • 通過ctx.mpserverless.db調用雲數據庫能力,如ctx.mpserverless.db.collection('user').find({ uid: args.uid })。
     • **通過ctx.cloud調用支付寶/阿里雲的各種開放接口能力,包括了支付寶的基礎/會員/支付/安全/營銷等開放接口,如創建小程序二維碼,調用ctx.cloud.base.qrcode.create({urlParam:'pages/index/index', queryParam:'key=value', describe:'我是二維碼'})**
     • 通過ctx.mpserverless.file調用文件存儲能力,如ctx.mpserverless.**file**.deleteFile(**args**.filePathUrl)。
     • 通過ctx.mpserverless.user獲取當前訪問用戶基本信息,如ctx.mpserverless.user.getInfo()。
     • 通過ctx.mpserverless.function調用雲函數能力,如mpserverless.function.invoke('dataAnalytics', {range: 30})調用其他雲函數。
     • 通過ctx.httpclient HTTP 請求方法,無需額外依賴,您就可以請求任何 HTTP 和 HTTPS 協議的 Web 服務。如ctx.httpclient.request(' https://www.alipay.com/x/notFound.htm' )。
    
module.exports = async (ctx) => {
  ctx.logger.info('%s %s', ctx.env.MP_SPACE_ID, ctx.args.username);
  const images = await ctx.mpserverless.db.collection('images').find({ owner: ctx.args.username });
  return { images };
};

雲調用

雲調用是基於小程序 Serverless 的雲函數來使用支付寶小程序開放接口的能力,可以方便的讓開發者在小程序中和雲函數中直接調用支付寶的後端開放接口,不需要關注服務端的相關配置,極大的減少了接入的流程,進一步降低了支付寶小程序的開發門檻。

雲調用開放能力說明

雲調用提供了基礎能力、營銷能力、會員能力、支付能力、安全能力和資金能力以及通用調用能力的接口調用,只需要開通雲調用,你就能在小程序端和雲函數端快捷的調用各類接口。

基礎能力

  • 用戶授權

• 獲取授權訪問令牌 cloud.base.oauth.getToken
• 刷新授權訪問令牌 cloud.base.oauth.refreshToken

// 在雲函數中使用雲調用,無需引入其他依賴,只需要使用ctx.cloud調用
module.exports = async function (ctx) {
  const res = await ctx.cloud.base.oauth.getToken({
    // code參數接收自雲函數調用處傳入的參數
    code: ctx.args.authCode
  });
  return res;
};
// 在小程序端使用雲調用
import cloud from 'alipaytest-serverless-sdk'

const res = await cloud.base.oauth.getToken('yourauthcode');
  • 小程序二維碼

• 創建小程序二維碼 cloud.base.qrcode.create

// 在雲函數中使用雲調用,無需引入其他依賴,只需要使用ctx.cloud調用
module.exports = async function (ctx) {
  const res = await ctx.cloud.base.qrcode.create({
    urlParam: 'pages/index/index',
    describe: '我的二維碼描述',
    queryParam: 'key=value'
  });
  return res;
};
// 在小程序端使用雲調用
import cloud from 'alipaytest-serverless-sdk'

const res = await cloud.base.qrcode.create('pages/index/index','key=value','我的二維碼描述');

營銷能力

  • 小程序模板消息

• 發送模板消息 cloud.marketing.templateMessage.send

// 在雲函數中使用雲調用,無需引入其他依賴,只需要使用ctx.cloud調用
module.exports = async function (ctx) {
  const res = await ctx.cloud.marketing.templateMessage.send({
    // 參數接收自雲函數調用端傳入的參數
    toUserId: ctx.args.toUserId,
    formId: ctx.args.formId,
    page: ctx.args.page,
    data: ctx.args.data,
    userTemplateId: ctx.args.userTemplateId  });
  return res;
};
// 在小程序端使用雲調用
import cloud from 'alipaytest-serverless-sdk'

const res = await cloud.marketing.templateMessage.send('2088xxxxx','2017010100000000580012345678','MDI4YzIxMDE2M2I5YTQzYjUxNWE4MjA4NmU1MTIyYmM=','page/component/index','');

資金能力

  • 無密轉賬到支付寶賬號

• 單筆轉賬 cloud.fund.transferAccount.transfer

// 在雲函數中使用雲調用,無需引入其他依賴,只需要使用ctx.cloud調用
module.exports = async function (ctx) {
  let payeeInfo = new Object({
    identity: this.data.payeeId,
    identity_type: 'ALIPAY_USER_ID'
  });
  const res = await ctx.cloud.fund.transferAccount.transfer({
    // 參數接收自雲函數調用端傳入的參數
    outBizNo: ctx.args.outBizNo,
    transAmount: ctx.args.transAmount,
    payee: payeeInfo,
    orderTitle: ctx.args.orderTitle
  });
  return res;
};
// 在小程序端使用雲調用
import cloud from 'alipaytest-serverless-sdk'

const res = await cloud.fund.transferAccount.transfer('155983843433000','1.00',{
    identity: '2088xxxxxxxxx',
  identity_type: 'ALIPAY_USER_ID'
},'轉賬標題');

支付能力

  • 當面付

• 當面付交易付款 cloud.payment.faceToFace.pay

// 在雲函數中使用雲調用,無需引入其他依賴,只需要使用ctx.cloud調用
module.exports = async function (ctx) {
  const res = await ctx.cloud.payment.faceToFace.pay({
    // 參數接收自雲函數調用端傳入的參數
    subject: ctx.args.subject,
    outTradeNo: ctx.args.outTradeNo,
    totalAmount: ctx.args.totalAmount,
    authCode: ctx.args.authCode
  });
  return res;
};
// 在小程序端使用雲調用
import cloud from 'alipaytest-serverless-sdk'

const res = await cloud.payment.faceToFace.pay('Iphone6 16G','20150320010101001','88.88','28763443825664394');

更多雲調用支持的開放能力可以在 開放平臺小程序云云調用專區 獲得

Leave a Reply

Your email address will not be published. Required fields are marked *