• 表单生成器(Form Builder)之mongodb表单数据查询——返回分页数据和总条数


      上一篇笔记将开始定义的存储结构处理了一下,将FormItems数组中的表单项都拿到mongodb document的最外层,和以前的关系型数据类似,之不过好多列都是动态的,不固定,不过这并没有什么影响。结果就是方便我们更好的查询和统计;还有一点就是转换之后从服务器端返回客户端的对象也是如此,这样更加方便了获取每个表单项的值(例如渲染列表)。

      我们的好多应用场景都是分页加载,并且都需要显示总的条数。以前是弄了两个API:一个是获取查询结果;一个是获取条数。为了这样一个功能要多发送一个API觉得有点浪费,之后便上网查了一下,这个问题前辈门已经遇到过了并且解决了,这里只是记录一下。我找到了几种处理方式,下面一一介绍一下。

      第一种

    //        $facet    New in version 3.4.
    db.getCollection('FormInstace').aggregate([
      {
        $facet: {
            totalCount: [
                { 
                    $match:{
                        FormId:'507048044944692000',
                        'FormItems':{$elemMatch:{'key':'1572493552001','value.id':"1"}}
                    } 
                },
                { $count: 'totalCount' }
            ],
            results: [
                { 
                    $match:{
                        FormId:'507048044944692000',
                        FormItems:{$elemMatch:{'key':'1572493552001','value.id':"1"}}
                    } 
                }
            ]
        }
      }
    ]);

      方案二

    //    方案2:
    async function getQuery() {
      let query = await db.collection.find({}).skip(5).limit(5); // returns last 5 items in db
      let countTotal = await query.count() // returns 10-- will not take `skip` or `limit` into consideration
      let countWithConstraints = await query.count(true) // returns 5 -- will take into consideration `skip` and `limit`
      return { query, countTotal } 
    }

      实际测试代码,和上面的代码类似,但是在C#中没有找到 count(true) 这样的方法

    var _client = new MongoClient("mongodb://127.0.0.1:27017");
    var _database = _client.GetDatabase("FormBuilder");
    var _collection = _database.GetCollection<BsonDocument>("FormInstace");
    var filter = Builders<BsonDocument>.Filter.Empty;
    filter &= Builders<BsonDocument>.Filter.Eq("FormId", "507048044944692000");
    filter &= Builders<BsonDocument>.Filter.ElemMatch("FormItems", Builders<BsonDocument>.Filter.Eq("key", "1572493552001") & Builders<BsonDocument>.Filter.Eq("value.id","1"));
    var _query = _collection.Find(filter);
    var totlaCount = _query.CountDocuments();
    var results = _query.Skip(0).Limit(10).ToList();
    Console.WriteLine($"共查询到{totlaCount}条记录");
    Console.ReadLine();

      以上两个方案都来自于:https://stackoverflow.com/questions/21803290/get-a-count-of-total-documents-with-mongodb-when-using-limit

      方案三

    //    方案3:
    db.getCollection('FormInstace').aggregate([
        {
            $match: {
                "FormItems.key": { $ne: null }
            }
        },
        {
            $addFields: {
                FormValueObj: {
                    $arrayToObject: {
                        $map: {
                            input: "$FormItems",
                            as: "field",
                            in: [ "$$field.key", "$$field.value" ]
                        }
                    }
                }
            }
        },
        {
          $replaceRoot: { newRoot: { $mergeObjects: [ "$FormValueObj", "$$ROOT" ] } }
        },
        {
            $project: {
                FormItems:0,
                FormValueObj:0
            }
        },
        { 
            $match:{
                FormId:'507048044944692000',
                "1572493552001.id":"1"
            } 
        },
        { 
            $group: {
                _id: null,
                count: { $sum: 1 },
                results: { $push: '$$ROOT' }
            }     
        },
        {
            $project:{_id:0,count:1, results: { $slice: [ "$results", 0, 10 ] }}
        }
    ]);

      方案三参考的是:https://medium.com/@kheengz/mongodb-aggregation-paginated-results-and-a-total-count-using-d2e23a00f5d5 但是上面的连接中也包括了这种方式……不管怎么说达到了我们想要的结果,并且支持分页!!!就是时间还是有点长,以后看看还能不能优化,如果有哪位大神有更好的方式,请告知,在这里表示感谢……

  • 相关阅读:
    bzoj2818
    bzoj1901
    bzoj1010
    loj6277
    bzoj1001
    bzoj1787
    选项卡
    日期选择器
    去掉文本框的外边框
    bootstarp 模态框大小尺寸的控制
  • 原文地址:https://www.cnblogs.com/du-blog/p/11832115.html
Copyright © 2020-2023  润新知