Browse Source

更新query:时间精确到时分秒,query和count使用aggregate(聚合管道)查询

lrf 3 years ago
parent
commit
8440ac7785
3 changed files with 91 additions and 21 deletions
  1. 46 0
      .github/workflows/nodejs.yml
  2. 1 1
      .travis.yml
  3. 44 20
      lib/service/crud-service.js

+ 46 - 0
.github/workflows/nodejs.yml

@@ -0,0 +1,46 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: Node.js CI
+
+on:
+  push:
+    branches:
+      - main
+      - master
+  pull_request:
+    branches:
+      - main
+      - master
+  schedule:
+    - cron: '0 2 * * *'
+
+jobs:
+  build:
+    runs-on: ${{ matrix.os }}
+
+    strategy:
+      fail-fast: false
+      matrix:
+        node-version: [8, 9]
+        os: [ubuntu-latest, windows-latest, macos-latest]
+
+    steps:
+    - name: Checkout Git Source
+      uses: actions/checkout@v2
+
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+
+    - name: Install Dependencies
+      run: npm i -g npminstall && npminstall
+
+    - name: Continuous Integration
+      run: npm run ci
+
+    - name: Code Coverage
+      uses: codecov/codecov-action@v1
+      with:
+        token: ${{ secrets.CODECOV_TOKEN }}

+ 1 - 1
.travis.yml

@@ -1,4 +1,4 @@
-sudo: false
+
 language: node_js
 node_js:
   - '8'

+ 44 - 20
lib/service/crud-service.js

@@ -1,6 +1,6 @@
 'use strict';
 
-const { isString, isArray, get } = require('lodash');
+const { isString, isArray, cloneDeep, head: getHead, get } = require('lodash');
 const { isNullOrUndefined, trimData } = require('naf-core').Util;
 const assert = require('assert');
 const { ObjectId } = require('mongoose').Types;
@@ -50,7 +50,7 @@ class CrudService extends NafService {
     if (sort && isString(sort)) {
       sort = { [sort]: desc ? -1 : 1 };
     } else if (sort && isArray(sort)) {
-      sort = sort.map((f) => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
+      sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
     }
 
     return await this.model.findOne(filter, projection).exec();
@@ -61,17 +61,35 @@ class CrudService extends NafService {
     if (sort && isString(sort)) {
       sort = { [sort]: desc ? -1 : 1 };
     } else if (sort && isArray(sort)) {
-      sort = sort.map((f) => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
+      sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
     }
-    filter = this.dealFilter(filter);
-    const rs = await this.model.find(trimData(filter), projection, { skip, limit, sort }).exec();
+    let condition = cloneDeep(filter);
+    condition = this.dealFilter(condition);
+    const pipeline = [{ $match: condition }];
+    // 先排序
+    if (sort) pipeline.push({ $sort: sort });
+    // 再进行分页
+    if (skip && limit) {
+      pipeline.push({ $skip: parseInt(skip) });
+      pipeline.push({ $limit: parseInt(limit) });
+    }
+    // 再将数据过滤
+    if (projection) pipeline.push({ $project: projection });
+    const rs = await this.model.aggregate(pipeline);
+    // const rs = await this.model.find(trimData(condition), projection, { skip, limit, sort }).exec();
     return rs;
   }
 
   async count(filter) {
-    filter = this.dealFilter(filter);
-    const res = await this.model.countDocuments(trimData(filter)).exec();
-    return res;
+    let condition = cloneDeep(filter);
+    condition = this.dealFilter(condition);
+    let count = 0;
+    const res = await this.model.aggregate([{ $match: condition }, { $count: 'id' }]);
+    if (res && isArray(res)) {
+      const head = getHead(res);
+      count = get(head, 'id', 0);
+    }
+    return count;
   }
 
   async queryAndCount(filter, options) {
@@ -87,12 +105,12 @@ class CrudService extends NafService {
   }
 
   turnFilter(filter) {
-    let str = /^%\S*%$/;
-    let keys = Object.keys(filter);
+    const str = /^%\S*%$/;
+    const keys = Object.keys(filter);
     for (const key of keys) {
-      let res = key.match(str);
+      const res = key.match(str);
       if (res) {
-        let newKey = key.slice(1, key.length - 1);
+        const newKey = key.slice(1, key.length - 1);
         if (!ObjectId.isValid(filter[key])) filter[newKey] = new RegExp(filter[key]);
         delete filter[key];
       }
@@ -102,30 +120,36 @@ class CrudService extends NafService {
 
   turnDateRangeQuery(filter) {
     const keys = Object.keys(filter);
+    const times = [];
     for (const k of keys) {
       if (k.includes('@')) {
         const karr = k.split('@');
         if (karr.length === 2) {
+          const prefix = karr[0];
           const type = karr[1];
           if (type === 'start') {
             if (filter[k] && filter[k] !== '') {
-              filter[karr[0]] = {
-                ...get(filter, karr[0], {}),
-                $gte: filter[k],
-              };
+              const obj = { key: prefix, opera: '$gte', value: new Date(filter[k]).toISOString() };
+              times.push(obj);
             }
           } else {
             if (filter[k] && filter[k] !== '') {
-              filter[karr[0]] = {
-                ...get(filter, karr[0], {}),
-                $lte: filter[k],
-              };
+              const obj = { key: prefix, opera: '$lte', value: new Date(filter[k]).toISOString() };
+              times.push(obj);
             }
           }
           delete filter[k];
         }
       }
     }
+    for (const i of times) {
+      const { key, opera, value } = i;
+      const obj = { [key]: { [opera]: value } };
+      if (!filter.$and) {
+        filter.$and = [];
+      }
+      filter.$and.push(obj);
+    }
     return filter;
   }
 }