Wiki

Clone wiki

JV2Mongo / Home

JV2Mongo

  • 2018年8月

概要:

JRA-VAN の蓄積系データを MongoDB にインポートするアプリケーションです。

使い方:

MongoDB の URL を入力し、接続ボタンを押してください。 対象とするデータのチェックボックスとタイムスタンプを入力し、取得ボタンを押してください。

説明:

JRA-VAN から提供される SDK の中にある、JVData_Struct.cs で定義されている構造体の定義に基づいてフィールドを定義し、JSON(BSON) 化しています。

  • 処理の都合上各構造体の中の id というフィールドは jvid という名前に変更してあります。
  • 値はすべて文字列型です。
  • JRA-VANの蓄積系の 11 データを基本的にそのままインポートします。

  • 例えば 'レース詳細' のデータ区分 0 は '該当レコード削除' の意味ですが、該当レコードを削除することなく、このレコードをそのまま追加します。

  • 例えば '馬毎レース情報' のデータ区分 9 の意味は仕様では 'レース中止' となっていますが、現実にはデータ修正のためのレコードが送られています。この場合でもそのまま追加します。
  • 馬名のような名前系のフィールドも、JRA-VANからきたとおり、後ろに全角スペースをつけたまま格納します。

なので、検索は通常の条件に加えて、id_MakeDate や DataKubun を考慮する必要があります。

例えば2018年1回小倉2日4R1番の馬毎レース情報 (SE) は結果データ (DataKubun = '7') が複数あります。(たぶん馬主名称の間違い)、 こういう場合に備えて head.MakeDate でソートして最新のデータを得てください。

use JRA-VAN

db.SE.find(
    {   'head.DataKubun': '7'
    ,   'jvid.Year' : '2018'
    ,   'jvid.JyoCD'    : '10'
    ,   'jvid.Kaiji'    : '01'
    ,   'jvid.Nichiji'  : '02'
    ,   'jvid.RaceNum'  : '04'
    ,   'Umaban'    : '01'
    }
).sort( { 'head.MakeDate.Year': -1, 'head.MakeDate.Month': -1, 'head.MakeDate.Day': -1 } ).limit( 1 )

また、馬名は全角スペースが後ろについていますので、以下のように正規表現でひく必要があります。騎手、調教師、馬主、生産者なども同様です。

完全一致

db.UM.find( { 'Bamei': /^ベガ / } )

前方一致

db.UM.find( { 'Bamei': /^ベガ/ } )

後方一致

db.UM.find( { 'Bamei': /ベガ / } )

部分一致

db.UM.find( { 'Bamei': /ベガ/ } )

また、同一馬でも複数データが存在しますので、head.MakeDate を考慮した方がいいでしょう。

処理の時間の都合上インデックスを作るのはいいアイディアだと思います。例えば以下のようにするのがよいでしょう。

db.RA.createIndex(
    {   'jvid.Year': 1
    ,   'jvid.JyoCD': 1
    ,   'jvid.Kaiji': 1
    ,   'jvid.Nichiji': 1
    ,   'jvid.RaceNum': 1
    }
)

db.SE.createIndex(
    {   'jvid.Year': 1
    ,   'jvid.JyoCD': 1
    ,   'jvid.Kaiji': 1
    ,   'jvid.Nichiji': 1
    ,   'jvid.RaceNum': 1
    ,   'Umaban': 1
    }
)

Node.js でレース結果を取得する例。

const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');

function
Dump( db, Year, JyoCD, Kaiji, Nichiji, RaceNum ) {
    db.collection( 'RA' ).find(
        {   'head.DataKubun': '7'
        ,   'jvid.Year'     : Year
        ,   'jvid.JyoCD'        : JyoCD
        ,   'jvid.Kaiji'        : Kaiji
        ,   'jvid.Nichiji'  : Nichiji
        ,   'jvid.RaceNum'  : RaceNum
        }
    ).sort( { 'head.MakeDate.Year': -1, 'head.MakeDate.Month': -1, 'head.MakeDate.Day': -1 } ).limit( 1 ).toArray(
        ( err, docs ) => {
            assert.equal( err, null )
            assert.equal( docs.length, 1 )
            console.log( docs[ 0 ][ "TorokuTosu" ] )
            for ( let i = 1; i <= docs[ 0 ][ "TorokuTosu" ]; i++ ) {
                db.collection( 'SE' ).find(
                    {   'head.DataKubun': '7'
                    ,   'jvid.Year'     : Year
                    ,   'jvid.JyoCD'        : JyoCD
                    ,   'jvid.Kaiji'        : Kaiji
                    ,   'jvid.Nichiji'  : Nichiji
                    ,   'jvid.RaceNum'  : RaceNum
                    ,   'Umaban'        : ( i < 10 ? "0" : "" ) + i
                    }
                ).sort( { 'head.MakeDate.Year': -1, 'head.MakeDate.Month': -1, 'head.MakeDate.Day': -1 } ).limit( 1 ).toArray(
                    ( err, docs ) => {
                        assert.equal( err, null )
                        assert.equal( docs.length, 1 )
                        console.log( i, docs[ 0 ][ "Bamei" ] )
                    }
                )
            }
        }
    )
}

MongoClient.connect(
    'mongodb://localhost:27017'
,   { useNewUrlParser: true }
,   ( err, client ) => {
        assert.equal( err, null )
        Dump( client.db( 'JRA-VAN' ), '2018', '10', '01', '02', '04' )
    //  client.close(); //  Causes Topology was destroyed
    }
)

Updated