MongoDB mapreduce

0

Sono nuovo alla programmazione e mongoDB e sto imparando mentre sto provando un mapreduce su un set di dati usando mongoDB. Finora ho convertito il csv in json e l'ho importato in un mongoDB usando la bussola.

Nella bussola i dati ora si presentano così:

_id     :5bc4e11789f799178470be53
    slug    :"bitcoin"
    symbol  :"BTC"
    name    :"Bitcoin"
    date    :"2013-04-28"
    ranknow :"1"
    open    :"135.3"
    high    :"135.98"
    low     :"132.1"
    close   :"134.21"
    volume  :"0"
    market  :"1500520000"
    close_ratio :"0.5438"
    spread  :"3.88"

Ho aggiunto ogni valore come indici come segue, è questo il processo giusto in modo da poter eseguire una mappa contro i dati?

db.testmyCrypto.getIndices() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "id", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "slug" : 1 }, "name" : "slug_1", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "symbol" : 2 }, "name" : "symbol_2", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "name" : 3 }, "name" : "name_3", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "data" : 4 }, "name" : "data_4", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "ranknow" : 4 }, "name" : "ranknow_4", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "ranknow" : 5 }, "name" : "ranknow_5", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "open" : 6 }, "name" : "open_6", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "high" : 7 }, "name" : "high_7", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "low" : 8 }, "name" : "low_8", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "volume" : 9 }, "name" : "volume_9", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "market" : 10 }, "name" : "market_10", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "close_ratio" : 11 }, "name" : "close_ratio_11", "ns" : "myCrypto.testmyCrypto" }, { "v" : 2, "key" : { "spread" : 13 }, "name" : "spread_13", "ns" : "myCrypto.testmyCrypto" } ]

Ho raschiato quanto sopra e ora sto facendo quanto segue dal link alla mappa-riduci. È l'uscita corretta, qualcuno?

> db.testmyCrypto.mapReduce(function() { emit( this.slug, this.symbol ); }, function(key, values) { return Array.sum( values ) },
... {
... query: { date:"2013-04-28" },
... out: "Date 04-28"
... }
... )
{
    "result" : "Date 04-28",
    "timeMillis" : 837,
    "counts" : {
        "input" : 0,
        "emit" : 0,
        "reduce" : 0,
        "output" : 0
    },
    "ok" : 1
}

Ho aggiunto le "coppie di valori chiave" ma non riesco a ottenere nulla dai dati.

> db.testmyCrypto.mapReduce(function() { emit( this.slug, this.symbol, this.name, this.date, this.ranknow, this.open, this.high, this.low, this.close, this.volume, this.market, this.close_ratio, this.spread ); }, function(key, values) { return Array.sum( values ) }, { query: { slug:"bitcoin" }, out: "Date 04-28" } )

{ "result" : "Date 04-28", "timeMillis" : 816,

"counts" : {
    "input" : 0,
    "emit" : 0,
    "reduce" : 0,
    "output" : 0
},
"ok" : 1 }

>

    
posta user1049286 20.10.2018 - 13:57
fonte

1 risposta

0

I've added each value as indices as follows, is this the right process so I can run a mapreduce against the data ?

Per MapReduce un indice è utile solo se supporta i tuoi criteri query . Sembra probabile che tu abbia molti più indici di quelli che sarebbero utili e manchi un indice per la tua query di esempio su date .

im doing the following from the link to the map-reduce. Is this the correct output

db.testmyCrypto.mapReduce(function() { emit( this.slug, this.symbol ); }, function(key, values) { return Array.sum( values ) },

L'esempio qui non ha senso poiché stai provando a fare una somma aritmetica del valore di stringa symbol . Anche i tuoi valori originali sembrano essere stringhe anziché numeri, il che non è l'ideale.

Quando importi il tuo JSON dovresti esaminare la conversione in tipi di dati appropriati come numero e data. mongoimport ha un'opzione --columnsHaveTypes che ti consente di trasmettere valori a tipi appropriati durante l'importazione.

Approccio consigliato

Penso che quello che stai cercando di fare è calcolare alcuni valori per un determinato simbolo di criptovaluta. Ove possibile, dovresti utilizzare il framework di aggregazione in quanto sarà più efficiente (e più facile da risolvere) rispetto a MapReduce.

Dato che hai menzionato che stai usando MongoDB Compass, puoi usare Aggregation Pipeline Builder in Compass 1.14+ per creare in modo interattivo un'aggregazione.

Ad esempio, utilizzando MongoDB 4.0 e scaricando lo stesso set di dati :

  • Aggiungi suggerimenti tipo colonna alla riga dell'intestazione in CSV utilizzando gli strumenti da riga di comando (potrebbe anche essere fatto utilizzando un editor di testo):

    headerline="slug.string(),symbol.string(),name.string(),date.date("2006-01-02"),ranknow.int32(),open.decimal(),high.decimal(),low.decimal(),close.decimal(),volume.decimal(),market.decimal(),close_ratio.decimal(),spread.decimal()"
    
    sed "1s/.*/$headerline/" crypto-markets.csv > testMyCrypto.csv
    
  • Importa i dati utilizzando mongoimport :

    mongoimport --headerline --columnsHaveTypes --type csv testmyCrypto.csv --db test --collection testmyCrypto --drop
    
  • Utilizzando la shell mongo (o UI bussola), aggiungi un indice per supportare query efficienti per data:

    db.testmyCrypto.createIndex({'date':1})
    
  • Esegui una query di aggregazione per aggiungere un campo daily_change calcolato con la differenza in open e close prezzi per ciascun simbolo in una determinata data:

    db.testmyCrypto.aggregate([
    { $match: {
    ​      date: new Date("2013-04-28")
    }},
    { $project: {
    ​       _id: 0,
    ​       symbol: "$symbol",
    ​       name: "$name",
    ​       daily_change: {
    ​          $subtract: [ "$open", "$close" ]
    ​       }
    }} 
    ]).pretty()
    
  • Risultati previsti:

    {
    ​   "symbol" : "BTC",
    ​   "name" : "Bitcoin",
    ​   "daily_change" : NumberDecimal("1.09")
    }
    {
    ​   "symbol" : "LTC",
    ​   "name" : "Litecoin",
    ​   "daily_change" : NumberDecimal("-0.05")
    }
    {
    ​   "symbol" : "PPC",
    ​   "name" : "Peercoin",
    ​   "daily_change" : NumberDecimal("0.000433")
    }
    {
    ​   "symbol" : "NMC",
    ​   "name" : "Namecoin",
    ​   "daily_change" : NumberDecimal("-0.01")
    }
    {
    ​   "symbol" : "NVC",
    ​   "name" : "Novacoin",
    ​   "daily_change" : NumberDecimal("-0.03")
    }
    {
    ​   "symbol" : "TRC",
    ​   "name" : "Terracoin",
    ​   "daily_change" : NumberDecimal("0.003901")
    }
    
risposta data 06.11.2018 - 01:22
fonte

Leggi altre domande sui tag