一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

玩轉(zhuǎn)Mongo計算

 raqsoft 2018-12-05

 MongoDB屬于 NoSql 中的基于分布式文件存儲的文檔型數(shù)據(jù)庫,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的。它支持的數(shù)據(jù)結(jié)構(gòu)非常松散,是類似 json 的 bson 格式,因此可以存儲比較復(fù)雜的數(shù)據(jù)類型。Mongo 最大的特點是它支持的查詢語言非常強大,其語法有點類似于面向?qū)ο蟮牟樵冋Z言,幾乎可以實現(xiàn)類似關(guān)系數(shù)據(jù)庫單表查詢的絕大部分功能,但是寫起來并不簡單。若能集算器 SPL 語言結(jié)合,處理起來就相對容易多了。

        現(xiàn)在我們針對 MongoDB 在計算方面的問題進行討論分析,通過集算器 SPL 語言加以改進,方便用戶使用 MongoDB?,F(xiàn)從如下情況加以說明:

1. 單表內(nèi)嵌數(shù)組結(jié)構(gòu)的統(tǒng)計............................................... 1
2. 單表內(nèi)嵌文檔求和......................................................... 3
3. 分段分組結(jié)構(gòu)................................................................ 5
4. 同構(gòu)表合并................................................................... 6
5. 關(guān)聯(lián)嵌套結(jié)構(gòu)情況 1...................................................... 8
6. 關(guān)聯(lián)嵌套結(jié)構(gòu)情況 2..................................................... 10
7. 關(guān)聯(lián)嵌套結(jié)構(gòu)情況 3..................................................... 11
8. 多字段分組統(tǒng)計........................................................... 14
9. 兩表關(guān)聯(lián)查詢............................................................... 16
10. 多表關(guān)聯(lián)查詢............................................................. 17
11. 指定數(shù)組查找............................................................. 19
12. 關(guān)聯(lián)表中的數(shù)組查找................................................... 20

1. 單表內(nèi)嵌數(shù)組結(jié)構(gòu)的統(tǒng)計

對嵌套數(shù)組結(jié)構(gòu)中的數(shù)據(jù)統(tǒng)計處理。查詢考試科目的平均分及每個學(xué)生的總成績情況。
測試數(shù)據(jù):
 
 腳本:
db.student.aggregate( [
  {\$unwind : "\$scroe"},
{\$group: {
  "_id":   {"lesson":"\$scroe.lesson"} ,
  "qty":{"\$avg":   "\$scroe.mark"}
  }
}
] ) db.student.aggregate( [
  {\$unwind : "\$scroe"},
{\$group: {
  "_id": {"name"   :"\$name"} ,
  "qty":{"\$sum" :   "\$scroe.mark"}
  }
}
 ] )

由于各科分數(shù) scroe 是按課目、成績記錄的數(shù)組結(jié)構(gòu),統(tǒng)計前需要將它拆解,將每科成績與學(xué)生對應(yīng),然后再實現(xiàn)分組計算。這需要熟悉 unwind 與 group 組合的應(yīng)用。

SPL 腳本:
 
  按課目統(tǒng)計的總分數(shù)
 腳本說明:

   A1:連接 mongo 數(shù)據(jù)庫。
   A2:獲取 student 表中的數(shù)據(jù)。
   A3:將 scroe 數(shù)據(jù)合并成序表,再按課程分組,計算平均分。
   A4:統(tǒng)計每個學(xué)生的成績后返回列名為 NAME、TOTAL 的序表。new 函數(shù)表示生成新序表。
   A5:關(guān)閉數(shù)據(jù)庫連接。
 
這個比較常用嵌套結(jié)構(gòu)統(tǒng)計的例子許多人遭遇過、需要先拆解,主要是熟悉 mongodb 對嵌套數(shù)據(jù)結(jié)構(gòu)的處理。

2. 單表內(nèi)嵌文檔求和

對內(nèi)嵌文檔中的數(shù)據(jù)求和處理, 下面要統(tǒng)計每條記錄的 income,output 的數(shù)量和。
 
測試數(shù)據(jù):
 
 Mongodb腳本:
var fields = [  "income", "output"];
db.computer.aggregate([  
   {  
      \$project:{  
         "values":{  
            \$filter:{  
               input:{  
                    "\$objectToArray":"\$\$ROOT"
               },
               cond:{  
                  \$in:[  
                     "\$\$this.k",
                     fields
                  ]
               }
            }
         }
      }
   },
   {  
      \$unwind:"\$values"
   },
   {  
      \$project:{  
         key:"\$values.k",
         values:{  
            "\$sum":{  
               "\$let":{  
                  "vars":{  
                     "item":{  
                        "\$objectToArray":"\$values.v"
                     }
                  },
                    "in":"\$\$item.v"
               }
            }
         }
      }
   },
   {\$sort: {"_id":-1}},
   { "\$group": {
    "_id": "\$_id",
    ''income'':{"\$first":   "\$values"},
    "output":{"\$last":   "\$values"}
    }},
]);

filter將income,output 部分信息存放到數(shù)組中,用 unwind 拆解成記錄,再累計各項值求和,按 _id 分組合并數(shù)據(jù)。

SPL 腳本:
 
 腳本說明:

   A1:連接數(shù)據(jù)庫
   A2:獲取 computer 表中的數(shù)據(jù)
   A3:將 income、output 字段中的數(shù)據(jù)分別轉(zhuǎn)換成序列求和,再與 ID 組合生成新序表
   A4:關(guān)閉數(shù)據(jù)庫連接。

獲取子記錄的字段值,然后求和,相對于 mongo 腳本簡化了不少。這個內(nèi)嵌文檔與內(nèi)嵌數(shù)組在組織結(jié)構(gòu)上有點類似,不小心容易混淆,注意與上例中的 scroe 數(shù)組結(jié)構(gòu)比較,寫出的腳本有所不同。

3. 分段分組結(jié)構(gòu)

統(tǒng)計各段內(nèi)的記錄數(shù)量。下面按銷售量分段,統(tǒng)計各段內(nèi)的數(shù)據(jù)量,數(shù)據(jù)如下: 
 分段方法:0-3000;3000-5000;5000-7500;7500-10000;10000 以上。

期望結(jié)果:

 
 Mongo 腳本
var a_count=0;
var b_count=0;
var c_count=0;
var d_count=0;
var e_count=0;
db.sales.find({
    
}).forEach( 
    function(myDoc) { 
        if (myDoc.SALES <3000)   { 
            a_count += 1;
        }
        else if (myDoc.SALES <5000)   { 
            b_count += 1;
        }
        else if (myDoc.SALES   <7500) { 
            c_count += 1;
        }
        else if (myDoc.SALES   <10000) { 
            d_count += 1;
        }
        else { 
            e_count += 1;
        }        
    } 
    );
    
print("a_count="+a_count)
print("b_count="+b_count)
print("c_count="+c_count)
print("d_count="+d_count)
print("e_count="+e_count)

這個需求按條件分段分組,mongodb 沒有提供對應(yīng)的 api,實現(xiàn)起來有點繁瑣,上面的程序是其中實現(xiàn)的一個例子參考,當(dāng)然也可以寫成其它實現(xiàn)形式。下面看看集算器腳本的實現(xiàn)。

SPL 腳本:
 
 腳本說明: 
   A1:定義 SALES 分組區(qū)間。
   A2:連接 mongodb 數(shù)據(jù)庫。
   A3:獲取 sales 表中的數(shù)據(jù)。
   A4:根據(jù) SALES 區(qū)間分組統(tǒng)計員工數(shù)。其中函數(shù) pseg()表示返回成員在序列中的區(qū)段序號,int() 表示轉(zhuǎn)換成整數(shù)。
   A5:關(guān)閉數(shù)據(jù)庫連接。

pseg 的使用讓 SPL 腳本精簡了不少。

4. 同構(gòu)表合并

具有相同結(jié)構(gòu)的多表數(shù)據(jù)合并。下面將兩個員工表數(shù)據(jù)合并。
Emp1:
 
  
 Mongo 腳本:
db.emp1.aggregate([
  {  "\$limit": 1},
  {   "\$facet": {
      "collection1": [
        {"\$limit": 1},
        { "\$lookup": {
          "from": "emp1",
          "pipeline": [{"\$match": {} }],
          "as": "collection1"
        }}
      ],
      "collection2": [
        {"\$limit": 1},
        { "\$lookup": {
          "from": "emp2",
          "pipeline": [{"\$match": {} }],
          "as": "collection2"
        }}
    ]
  }},
  {   "\$project": {
      "data": {
        "\$concatArrays": [
          {"\$arrayElemAt": ["\$collection1.collection1", 0]   },
          {"\$arrayElemAt": ["\$collection2.collection2", 0]   },
        ]
    }
  }},
  {  "\$unwind": "\$data"},
  {  "\$replaceRoot": { "newRoot": "\$data"} }
])

通過 facet 將兩表數(shù)據(jù)先存入各自的數(shù)組中,然后 concatArrays 將數(shù)組合并,unwind 拆解子記錄后,并將它呈現(xiàn)在最外層。SPL 腳本實現(xiàn)則沒有那么多“花樣”。

SPL 腳本:
 
 腳本說明:

   A1:連接 mongodb 數(shù)據(jù)庫。
   A2:獲取 emp1 表中的數(shù)據(jù)。
   A3:獲取 emp2 表中的數(shù)據(jù)。
   A4:合并兩表數(shù)據(jù)。
   A5:關(guān)閉數(shù)據(jù)庫連接。

熟悉 sql 語句的 mongo 初學(xué)者面對數(shù)據(jù)合并的 mongo 腳本,估計首次遇到時有點“懵”,SPL 腳本就顯得自然易懂了。

5. 關(guān)聯(lián)嵌套結(jié)構(gòu)情況 1

兩個關(guān)聯(lián)表,表 A 與表 B 中的內(nèi)嵌文檔信息關(guān)聯(lián), 且返回的信息在內(nèi)嵌文檔中。表 childsgroup 字段 childs 是嵌套數(shù)組結(jié)構(gòu),需要合并的信息 name 在其下。
history:
 
 

表History中的child_id與表childsgroup中的childs.id關(guān)聯(lián),希望得到下面結(jié)果:
{
    “_id” : ObjectId(“5bab2ae8ab2f1bdb4f434bc3”),
    “id” : “001”,
    “history” : “today worked”,
    “child_id” : “ch001”,
    “childInfo” :
    {
   “name” : “a”
    }
   ………………
}

Mongo 腳本

db.history.aggregate([
    {\$lookup: {
        from:   "childsgroup",
        let: {child_id:   "\$child_id"},
        pipeline: [
            {\$match: {   \$expr: { \$in: [ "\$\$child_id", "\$childs.id"] } } },
            {\$unwind:   "\$childs"},
            {\$match: {   \$expr: { \$eq: [ "\$childs.id", "\$\$child_id"] } } },
            {\$replaceRoot: {   newRoot: "\$childs.info"} }
            ],
            as:   "childInfo"
        }},
  {"\$unwind": "\$childInfo"}
])

這個腳本用了幾個函數(shù)lookup、pipeline、match、unwind、replaceRoot處理,一般 mongodb 用戶不容易寫出這樣復(fù)雜腳本;那我們再看看 spl 腳本的實現(xiàn):

SPL 腳本:
 
 
腳本說明:
   A1:連接 mongodb 數(shù)據(jù)庫。
   A2:獲取 history 表 中的數(shù)據(jù)。
   A3:獲取 childsgroup 表 中的數(shù)據(jù)。
   A4:將 childsgroup 中的 childs 數(shù)據(jù)提取出來合并成序表。
   A5:表 history 中的 child_id 與表 childs 中的 id 關(guān)聯(lián)查詢,追加 name 字段, 返回序表。
   A6:關(guān)閉數(shù)據(jù)庫連接。

相對 mongodb 腳本寫法,SPL 腳本的難度降低了不少,省去了熟悉有關(guān) mongo 函數(shù)的用法,如何去組合處理數(shù)據(jù)等,節(jié)約了不少時間。

6. 關(guān)聯(lián)嵌套結(jié)構(gòu)情況 2

兩個關(guān)聯(lián)表,表 A 與表 B 中的內(nèi)嵌文檔信息關(guān)聯(lián), 將信息合并到內(nèi)嵌文檔中。表 txtPost 字段 comment 是嵌套數(shù)組結(jié)構(gòu),需要把 comment_content 合并到其下。
 
 Mongo 腳本

db.getCollection("txtPost").aggregate([

  {  "\$unwind": "\$comment"},

  {   "\$lookup": {

      "from": "txtComment",

      "localField": "comment.comment_no",

      "foreignField": "comment_no",

      "as": "comment.comment_content"

  }},

  {  "\$unwind": "\$comment.comment_content"},

  {  "\$addFields": { "comment.comment_content":   "\$comment.comment_content.comment_content"}},

  {   "\$group": {

      "_id": "\$_id",

      ''post_no'':{"\$first": "\$post_no"},

      "comment": {"\$push": "\$comment"}

      }},

 

    ]).pretty()txtPost 按 comment 拆解成記錄,然后與表 txtComment 關(guān)聯(lián)查詢,將其結(jié)果放到數(shù)組中,再將數(shù)組拆解成記錄,將comment_content 值移到 comment 下,最后分組合并。

SPL 腳本:
 
 腳本說明: 
   A1:連接 mongodb 數(shù)據(jù)庫。
   A2:獲取 txtPost 表 中的數(shù)據(jù)。
   A3:獲取 txtComment 表 中的數(shù)據(jù)。
   A4:將序表 A2 下的 comment 與 post_no 組合成序表,其中 post_no 改名為 pno。
   A5:序表 A4 通過 comment_no 與序表 A3 關(guān)聯(lián),追加字段 comment_content,將其改名為 Content。
   A6:按 pno 分組返回序表,~ 表示當(dāng)前記錄。
   A7:關(guān)閉數(shù)據(jù)庫連接。

7. 關(guān)聯(lián)嵌套結(jié)構(gòu)情況 3

兩個關(guān)聯(lián)表,表 A 與表 B 中的內(nèi)嵌文檔信息關(guān)聯(lián), 且返回的信息在記錄上。表 collection2 字段 product 是嵌套數(shù)組結(jié)構(gòu),返回的信息是 isCompleted 等字段。
測試數(shù)據(jù):

collection1:
{
   _id: ''5bc2e44a106342152cd83e97'',
   description:
    {
   status: ''Good'',
   machine: ''X''
  },
   order: ''A'',
   lot: ''1''
   };
  
collection2:
{
   _id: ''5bc2e44a106342152cd83e80'',
   isCompleted: false,
   serialNo: ''1'',
   batchNo: ''2'',
   product: [ // note the subdocuments here
  {order: ''A'', lot: ''1''},
     {order: ''A'', lot: ''2''}
    ]
}

期待結(jié)果
{
   _id: 5bc2e44a106342152cd83e97,
   description:
    {
   status: ''Good'',
   machine: ''X'',
    },
   order: ''A'',
   lot: ''1'' ,
   isCompleted: false,
   serialNo: ''1'',
   batchNo: ''2''
}

Mongo 腳本

db.collection1.aggregate([{
    \$lookup:   {
  from:   "collection2",
  let:   {order: "\$order", lot: "\$lot"},
  pipeline:   [{
   \$match:   {
   \$expr:{  \$in: [ { order: "\$\$order", lot: "\$\$lot"},   "\$product"] }
   }  
   }],  
   as:   "isCompleted"
   }  
  },   {
   \$addFields:   {
   "isCompleted":   {\$arrayElemAt: [ "\$isCompleted", 0] }
   }  
  },   {
   \$addFields:   { // add the required fields to the top level structure
   "isCompleted":   "\$isCompleted.isCompleted",
     "serialNo":   "\$isCompleted.serialNo",
   "batchNo":   "\$isCompleted.batchNo"
  }  
}])

lookup 兩表關(guān)聯(lián)查詢,首個 addFields獲取isCompleted數(shù)組的第一個記錄,后一個addFields 轉(zhuǎn)換成所需要的幾個字段信息

SPL 腳本:
 
 
腳本說明:
   A1:連接 mongodb 數(shù)據(jù)庫。
   A2:獲取 collection1 表 中的數(shù)據(jù)。
   A3:獲取 collection2 表 中的數(shù)據(jù)。
   A4:根據(jù)條件 order, lot 從序表 A2 中查詢記錄,然后追加序表 A3 中的字段 serialNo, batchNo,返回合并后的序表。
   A5:關(guān)閉數(shù)據(jù)庫連接。

實現(xiàn)從數(shù)據(jù)記錄中的內(nèi)嵌結(jié)構(gòu)中篩選,將符合條件的數(shù)據(jù)合并成新序表。

8. 多字段分組統(tǒng)計

統(tǒng)計分類項下的總數(shù)及各子項數(shù)。下面統(tǒng)計按 addr 分類 book 數(shù)及其下不同的 book 數(shù)。
 
 Mongo 腳本
db.books.aggregate([
    {   "\$group": {
          "_id": {
              "addr": "\$addr",
              "book": "\$book"
        },
          "bookCount": {"\$sum": 1}
    }},
    {   "\$group": {
          "_id": "\$_id.addr",
          "books": { 
              "\$push": { 
                  "book": "\$_id.book",
                  "count": "\$bookCount"
            },
        },
          "count": {"\$sum": "\$bookCount"}
    }},
    {  "\$sort": { "count": -1} },
    {   "\$project": {
          "books": {"\$slice": [ "\$books", 2] },
          "count": 1
    }}
]).pretty()

先按 addr,book 分組統(tǒng)計 book 數(shù),再按 addr 分組統(tǒng)計 book 數(shù),調(diào)整顯示順序

SPL腳本:

 
腳本說明:

   A1:連接 mongodb 數(shù)據(jù)庫。
   A2:獲取books表中的數(shù)據(jù)。
   A3:按 addr,book 分組統(tǒng)計 book 數(shù),
   A4:再按 addr 分組統(tǒng)計 book 數(shù)。
   A5:將 A4 中的 Total 按 addr 關(guān)聯(lián)后合并到序表中。
   A6:關(guān)閉數(shù)據(jù)庫連接。

9. 兩表關(guān)聯(lián)查詢

從關(guān)聯(lián)表中選擇所需要的字段組合成新表。

Collection1:

 
 Mongo 腳本
db.c1.aggregate([
    {   "\$lookup": {
      "from": "c2",
          "localField": "user1",
          "foreignField": "user1",
          "as": "collection2_doc"
      }},
    {  "\$unwind": "\$collection2_doc"},
    {   "\$redact": {
          "\$cond": [
              {"\$eq": [ "\$user2",   "\$collection2_doc.user2"] },
              "\$\$KEEP",
              "\$\$PRUNE"
          ]
      }},
    {   "\$project": {
          "user1": 1,
          "user2": 1,
          "income": "\$income",
          "output": "\$collection2_doc. output"
      }}
      ]).pretty()

lookup 兩表進行關(guān)聯(lián)查詢,redact 對記錄根據(jù)條件進行遍歷處理,project 選擇要顯示的字段。

SPL腳本:

 
 腳本說明:

   A1:連接 mongodb 數(shù)據(jù)庫。
   A2:獲取c1表中的數(shù)據(jù)。
   A3:獲取c2表中的數(shù)據(jù)。
   A4:兩表按字段 user1,user2 關(guān)聯(lián),追加序表 A3 中的 output 字段,返回序表。
   A5:關(guān)閉數(shù)據(jù)庫連接。

通過 join 把兩個關(guān)聯(lián)表不同的字段合并成新表。

10. 多表關(guān)聯(lián)查詢

多于兩個表的關(guān)聯(lián)查詢,結(jié)合成一張大表。

 
 合并后的結(jié)果:

{
    "_id" : ObjectId("5901a4c63541b7d5d3293766"),
    "firstName" : "shubham",
    "lastName" : "verma",
 
    "address" : {
  "address" : "Gurgaon"
    },
    "social" : {
  "fbURLs" : "http://www.",
  "twitterURLs" : "http://www.twitter.com"
    }
}

Mongo 腳本

db.doc1.aggregate([
    {\$match:   { _id: ObjectId("5901a4c63541b7d5d3293766") } },
    {
    \$lookup:
  {
     from: "doc2",
     localField: "_id",
     foreignField: "userId",
     as: "address"
  }
    },
    {
    \$unwind: "\$address"
    },
    {
    \$project: {
     "address._id": 0,
     "address.userId": 0,
     "address.mob": 0
  }
    },
    {
    \$lookup:
  {
     from: "doc3",
     localField: "_id",
     foreignField: "userId",
     as: "social"
  }
    },
    {
    \$unwind: "\$social"
    },
 
  {  
    \$project:   {  
    "social._id": 0,  
    "social.userId": 0
    }
 }
]).pretty();

由于 Mongodb 數(shù)據(jù)結(jié)構(gòu)原因,寫法也多樣化,展示也各不相同。

SPL 腳本:
 
 此腳本與上面例子類似,只是多了一個關(guān)聯(lián)表,每次 join 就新增加字段,最后疊加構(gòu)成一張大表。.

SPL 腳本的簡潔性、統(tǒng)一性就非常明顯。

11. 指定數(shù)組查找

從指定的數(shù)組中查找符合條件的記錄。所給的數(shù)組為:["Chemical", "Biology", "Math"]。

測試數(shù)據(jù):

 
 Mongodb 腳本

var field = ["Chemical",   "Biology", "Math"]
db.student.aggregate([
  {   "\$project": {
      "name":1,
      "lessons": {
        "\$filter": {
          "input": "\$lesson",
          "cond": {
            "\$in": [
              "\$\$this",
              field
            ]
          }
        }
        },
      }},
    {  "\$project":   {"name":1,"lessons":1,"sizeOflesson":   {"\$size": "\$lessons"} }},
    {  \$match: { "sizeOflesson":{ \$gt: 0}}}
])

查詢選修課包含["Chemical", "Biology", "Math"]的同學(xué)。

SPL 腳本:
 
 腳本說明:

   A1:定義查詢條件科目數(shù)組。
   A2:連接 mongodb 數(shù)據(jù)庫。
   A3:獲取 student 表中的數(shù)據(jù)。
   A4:查詢存在數(shù)組中的科目記錄。
   A5:生成字段為 name, lesson 的新序表,其中符合條件的值存放在字段 lesson 中
   A6:關(guān)閉數(shù)據(jù)庫連接。

集算器對給定數(shù)組中查詢記錄的實現(xiàn)更簡明易懂。

12. 關(guān)聯(lián)表中的數(shù)組查找

從關(guān)聯(lián)表記錄數(shù)據(jù)組中查找符合條件的記錄, 用給定的字段組合成新表。

測試數(shù)據(jù):

 
 Mongo 腳本
db.users.aggregate([ 
  { "\$lookup": { 
    "from" :   "workouts", 
    "localField" :   "workouts", 
    "foreignField" :   "_id", 
    "as" :   "workoutDocumentsArray" 
  }}, 
  {\$project: {   _id:0,workouts:0} } , 
  {"\$unwind":   "\$workoutDocumentsArray"},; 
  {"\$replaceRoot": {   "newRoot":  { \$mergeObjects:   [ "\$\$ROOT", "\$workoutDocumentsArray"] } } }, 
  {$project: {   workoutDocumentsArray: 0} } 
  ]).pretty()

把關(guān)聯(lián)表 users,workouts 查詢結(jié)果放到數(shù)組中,再將數(shù)組拆解,提升子記錄的位置,去掉不需要的字段。

SPL 腳本:
 
 腳本說明: 
    A1:連接 mongodb 數(shù)據(jù)庫。
    A2:獲取 users 表中的數(shù)據(jù)。
    A3:獲取 workouts 表中的數(shù)據(jù)。
    A4:查詢序表 A3 的 _id 值存在于序表 A2 中 workouts 數(shù)組的記錄, 并追加 name 字段, 返回合并的序表。
    A5:關(guān)閉數(shù)據(jù)庫連接。

由于需要獲取序列的交集不為空為條件,故將 _id 轉(zhuǎn)換成序列。

        Mongo 存儲的數(shù)據(jù)結(jié)構(gòu)相對關(guān)聯(lián)數(shù)據(jù)庫更復(fù)雜、更靈活,其提供的查詢語言也非常強、能適應(yīng)不同的情況,需要了解函數(shù)也不少,函數(shù)之間的結(jié)合更是變化無窮,因此要掌握并熟悉應(yīng)用它并非易事。集算器的離散性、易用性恰好能彌補 Mongo 這方面的不足,它降低了 mongo 學(xué)習(xí)成本及使用 mongo 操作的復(fù)雜度、難度,讓 mongo 的功能得到更充分的展現(xiàn),同時也希望 mongo 越來越受到廣大愛好者的青睞。

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    白丝美女被插入视频在线观看| 东京热一二三区在线免| 国产成人精品在线一区二区三区| 亚洲一区二区精品免费视频| 欧美三级精品在线观看| 夫妻性生活黄色录像视频| 人妻少妇av中文字幕乱码高清| 韩日黄片在线免费观看| 日本高清不卡在线一区| 国产亚洲精品一二三区| 精品视频一区二区三区不卡| 国产在线一区二区免费| 色播五月激情五月婷婷| 开心激情网 激情五月天| 人人爽夜夜爽夜夜爽精品视频| 国产精品乱子伦一区二区三区| 欧美一区二区三区99| 99久久成人精品国产免费| 国产精品福利一二三区| 国产精品丝袜一二三区| 日韩精品在线观看一区| 美国欧洲日本韩国二本道| 久久精品国产一区久久久| 国产在线一区中文字幕 | 91欧美一区二区三区成人| 伊人网免费在线观看高清版| 久热久热精品视频在线观看| 欧美自拍系列精品在线| 老富婆找帅哥按摩抠逼视频| 日韩精品福利在线观看| 国产在线观看不卡一区二区| 日韩精品一区二区亚洲| 欧美日韩精品久久第一页| 国产日韩欧美在线播放| 中字幕一区二区三区久久蜜桃| 国产精品福利一二三区| 日韩人妻一区二区欧美| 粉嫩一区二区三区粉嫩视频| 蜜臀人妻一区二区三区| 欧美一级特黄大片做受大屁股| 五月综合婷婷在线伊人|