(メモ)mongodbから抽出したいデータだけ抽出,

## mongodbから抽出したいデータだけ抽出する

■2017年10月1日の日報抽出(pages)
> db.pages.find({path: "/user/test/日報/2017/10/01"})
{ "_id" : ObjectId("59c3d9584428d8f705f5dce2"), "redirectTo" : null, "updatedAt" : ISODate("2017-09-21T15:23:04.655Z"), "lastUpdateUser" : ObjectId("58fa23767ffd2fbb09ef557d"), "creator" : ObjectId("58fa23767ffd2fbb09ef557d"),
 "path" : "/user/test/日報/2017/10/01", "createdAt" : ISODate("2017-09-21T15:23:04.592Z"), "extended" : "{}", "commentCount" : 0, "seenUsers" : [ ObjectId("58fa23767ffd2fbb09ef557d") ], "liker" : [ ], "grantedUsers" :
 [ ObjectId("58fa23767ffd2fbb09ef557d") ], "grant" : 1, "status" : "published", "__v" : 1, "revision" : ObjectId("59c3d9584428d8f705f5dce3") }

■2017年10月の日報を抽出(pages)
db.pages.find({path: "/user/test/日報/2017/10"})

■2017年10月1日の本文抽出(revisions)
> db.revisions.find({path: "/user/test/日報/2017/10/01"})
{ "_id" : ObjectId("59c3d9584428d8f705f5dce3"), "author" : ObjectId("58fa23767ffd2fbb09ef557d"), "body" : "# 日報/2017/10/01\r\n\r\n# 使用オーダ\r\n\r\n|開始時刻|終了時刻|オーダ番号|備考|\r\n| --- | --- | --- | --- |\r\n|08:30|17:15|7002|支援|\r\n|17:15|19:00|その他|業務報告等|\r\n\r\n# 関連FAQ\r\n\r\n* 搬送の規約番号に「0」と入力しても機能するのか。　　←その日登録するつもりor登録した FAQのタイトル\r\n* テストの見分け方はありますか？\r\n\r\n ", "path" : "/user/test/日報/2017/10/01", "createdAt" : ISODate("2017-09-21T15:23:04.651Z"), "format" : "markdown", "__v" : 0 }

■/を入れることにより表示される(revisions)
db.revisions.find({path: /^\/user\/test\/日報\/2017\/10\//})

■revisionに登録されている本文が表示される
db.pages.find( { "path": /^\/user\/test\/日報\/2017\/10\//} ).forEach(function(doc){db.revisions.find({ "_id": doc.revision }).forEach(function(item){print( item.path );item.body.match(/\|\d+:\d+\|.*\|\d\d\d\d\|.*\|.*\|/gi).forEach(function( order ){print( order );})})})

本文表示
/user/test/日報/2017/10/01
|08:30|17:15|東京|1000|東京支援|鈴木|
/user/test/日報/2017/10/02
|08:30|17:15|東京|1000|東京支援|鈴木|

■サンプルテキストにオーダ表(2017年10月のtest日報)を代入する
cat <<'EOF' |mongo > sample.txt
use crowidb
db.pages.find( { "path": /^\/user\/test\/日報\/2017\/10\//} ).forEach(
function(doc){
    db.revisions.find({ "_id": doc.revision }).forEach(function(item){
        print( item.path );
        item.body.match(/\|\d+:\d+\|.*\|\d\d\d\d\|.*\|.*\|/gi).forEach(
        function( order ){
                  print( order );
        })
    })
})
EOF

■オーダ管理表示(|非表示）
cat sample.txt | gawk 'BEGIN{FS="|"; OFS=",";} /^\/user/{ match($0, /\/日報\/([0-9]+\/[0-9]+\/[0-9]+)$/, m); date=m[1]; } /\|/{print date,$2,$3,$4,$5,$6;}'

表示
2017/10/01,08:30,17:15,東京,7002,東京支援
2017/10/02,08:30,17:15,東京,7002,東京支援
2017/10/05,08:30,17:15,東京,7002,東京支援

■サンプルファイルなしで実行
cat <<'EOF' |mongo | gawk 'BEGIN{FS="|"; OFS=",";} /^\/user/{ match($0, /\/日報\/([0-9]+\/[0-9]+\/[0-9]+)$/, m); date=m[1]; } /\|/{sub(/:/,"",$2);sub(/:/,"",$3);print date,$2,$3,$4,$5,$6;}'
use crowidb
db.pages.find( { "path": /^\/user\/test\/日報\/2017\/10\//} ).forEach(
function(doc){
    db.revisions.find({ "_id": doc.revision }).forEach(function(item){
        print( item.path );
        item.body.match(/\|\d+:\d+\|.*\|\d\d\d\d\|.*\|.*\|/gi).forEach(
        function( order ){
                  print( order );
        })
    })
})
EOF

表示
2017/10/01,08:30,17:15,東京,7002,東京支援
2017/10/02,08:30,17:15,東京,7002,東京支援
2017/10/05,08:30,17:15,東京,7002,東京支援

■シェル
createOrder.sh
\-------------
\#!/bin/sh

TARGET=$1; #   /^\/user\/test\/日報\/2017\/10\//

cat <<EOF |mongo | gawk 'BEGIN{FS="|"; OFS=",";} /^\/user/{ match($0, /\/日報\/([0-9]+\/[0-9]+\/[0-9]+)$/, m); date=m[1]; } /\|/{sub(/:/,"",$2);sub(/:/,"",$3);print date,$2,$3,$4,$5,$6;}' > sample.csv
use crowidb
db.pages.find( { "path": ${TARGET}} ).forEach(
function(doc){
    db.revisions.find({ "_id": doc.revision }).forEach(function(item){
        print( item.path );
        item.body.match(/\|\d+:\d+\|.*\|\d\d\d\d\|.*\|.*\|/gi).forEach(
        function( order ){
                  print( order );
        })
    })
})
EOF

■ファイルダウンロード
[root@localhost ~]# cat /var/www/html/downroad.php
<html>
<body>
 <?php
  $args='/^\/user\/' . $_GET['user'] . '\/日報\/' . $_GET['y'] . '\/' . $_GET['m'] . '\//';
  $cmd="/root/createOrder.sh" . " " . $args;
  $output = array();

  exec($cmd,$output); // スクリプトを実行

// 実行結果を出力
 foreach($output as $line){
 echo $line;
 }
 ?>

</body>
</html>


[root@localhost ~]# cat createOrder.sh
#!/bin/sh

TARGET=$1; #   /^\/user\/test\/日報\/2017\/10\//

cat <<EOF |mongo | gawk 'BEGIN{FS="|"; OFS=",";} /^\/user/{ match($0, /\/日報\/([0-9]+\/[0-9]+\/[0-9]+)$/, m); date=m[1]; } /\|/{sub(/:/,"",$2);sub(/:/,"",$3);print date,$2,$3,$4,$5,$6;}' > sample.csv
use crowidb
db.pages.find( { "path": ${TARGET}} ).forEach(
function(doc){
    db.revisions.find({ "_id": doc.revision }).forEach(function(item){
        print( item.path );
        item.body.match(/\|\d+:\d+\|.*\|\d\d\d\d\|.*\|.*\|/gi).forEach(
        function( order ){
                  print( order );
        })
    })
})
EOF

###最終体系
<?php
  header("Content-Type: application/octet-stream");
  header("Content-Disposition: attachment; filename=order.csv"); -->

  $args='/^\\\/user\\\/' . $_GET['user'] . '\\\/日報\\\/' . $_GET['y'] . '\\\/' . $_GET['m'] . '\\\//';
  $cmd="/var/www/html/order/createOrder.sh" . " " . $args;
  $output = array();

  exec($cmd,$output); // スクリプトを実行
// 実行結果を出力
 foreach($output as $line){
 echo mb_convert_encoding($line . "\r\n", "SJIS", "UTF-8");
 }
 ?>

###対象月分のみ出力

<li><a href="http://192.168.179.199/downroad.php?user={{path.split("/")[2];}}&y={{path.split("/")[4];}}&m={{path.split("/")[5];}}">csv出力</a></li>

###日付出力
<p>
[root@localhost order]# cat kinmukanri_formatorder.awk
#!/usr/bin/gawk -f

BEGIN{
    FS="|";
    OFS=",";
    # 1日～31日まで3行分ずつの空行csv情報を持つようにlineを初期設定。
    for( day=1; day <= 31; day++ ){
        for( idx=0; idx<3; idx++ ){
            line[day,idx] = day ",,,,,";
        }
        idxmax[day]=idx;
    }
}

/^\/user/{
    match($0, /\/日報\/([0-9]+\/[0-9]+\/([0-9]+))$/, m);
    date=m[1];
    day=m[2]+0;
    idx=0;
}

/\|/{
    sub(/:/,"",$2);
    sub(/:/,"",$3);
    # オーダー情報を記憶
    if( idx == 0 ){
        start[day] = $2;
    }
    end[day] = $3;
    line[day,idx++] = (date "," $2 "," $3 "," $4 "," $5 "," $6);
    if( idx > idxmax[day] ){
        idxmax[day]=idx;
    }
}

END{
    # 記憶しておいた情報を出力
    for( day=1; day <= 31; day++ ){
        for( idx=0; idx<idxmax[day]; idx++ ){
            print line[day,idx];
        }
    }

    # 勤務管理表用にまとめた出力
    printf("\n");
    for( day=1; day <= 31; day++ ){
        print start[day] "," end[day];
    }
}</p>