2012-11-04 12 views
6

ho memorizzare i nostri log del server web in MongoDB e lo schema è simile a quanto segue:

[ 
    { 
    "_id" : 12345, 
    "url" : "http://www.mydomain.com/xyz/abc.html", 
    .... 
    }, 
    .... 
] 

Sto cercando di utilizzare l'operatore $project per rimodellare questo schema un po 'prima di iniziare a passare la mia collezione attraverso una pipeline di aggregazione. Fondamentalmente, ho bisogno di aggiungere un nuovo campo chiamato "tipo" che verrà utilizzato in seguito per eseguire il raggruppamento. La logica per il nuovo campo è piuttosto semplice.

if "url" contains "pattern_A" then set "type" = "sales lead"; 
else if "url" contains "pattern_B" then set "type" = "existing client"; 
... 

Sto pensando che avrebbe dovuto essere qualcosa di simile:

db.weblog.aggregate(
    { 
    $project : { 
     type : { /* how to implement the logic??? */ } 
    } 
    } 
); 

So come fare questo usando la mappa-ridurre (impostando il "keyf" attributo a una funzione JS personalizzato che implementa la logica sopra) ma sto cercando di utilizzare lo new aggregation framework per farlo. Ho provato ad implementare la logica usando il expression operators ma finora non riuscivo a farlo funzionare. Qualsiasi aiuto/suggerimento sarebbe molto apprezzato!

risposta

0

È necessario utilizzare la combinazione di più operatori ed espressioni.

Per prima cosa, l'operatore $cond in $project consente di implementare se non altro la logica.

$cond: accetta un array di tre elementi, prima un'espressione booleana, il secondo e il terzo sono valori da utilizzare per il valore del campo - se l'espressione booleana è vera, quindi utilizza il secondo elemento per il valore, se non il terzo elemento.

è possibile nidificare questi in modo che il terzo elemento sia esso stesso un'espressione $cond per ottenere if-then-else-if-then-etc.

la manipolazione delle stringhe è un po 'scomoda ma è disponibile $substr.

Se pubblichi alcuni esempi di cosa esattamente hai provato, potrei riuscire a capire perché non ha funzionato.

+0

Grazie per la risposta. Il tuo suggerimento è stata la prima cosa che ho tentato e ho raggiunto rapidamente un punto morto quando ho capito che non ero in grado di verificare l'esistenza di un modello di stringa usando gli operatori di stringhe supportati.Ho bisogno di qualcosa come indexOf() per cercare determinati pattern nell'URL. – Edenbauer

+0

dove può avvenire la sottostringa nella "url"? È qualcosa che è possibile archiviare nel momento in cui inizialmente si scrive il documento? –

+0

Sto avendo una situazione simile. Ho due campi A e B e la loro esistenza nel documento si escludono a vicenda. Devo raggruppare per A quando A esiste e raggruppare per B quando B esiste, ma sembra che tu non possa avere $ cond in un progetto $..Io ho provato a scrivere $ project in due modi: {$ project: {MyKey : {$ cond: [{$ exists: ["$ A", vero]}, "$ A", "$ B"]}}} e {$ progetto: {MyKey: {$ cond: [{" A ": {$ esiste: true}}," $ A "," $ B "]}}} Ma continuo a ricevere l'errore: { " errmsg ":" eccezione: operatore non valido '$ esiste' ", "codice": 15999, "ok": 0 } ... Forse è solo una fastidiosa cosa della sintassi :( –

1

Sto condividendo la mia "soluzione" nel caso in cui altri incontrino gli stessi bisogni come il mio.

Dopo aver ricercato per un paio di settimane, come suggerito da @ asya-kamsky in uno dei suoi commenti, ho deciso di aggiungere un campo calcolato al mio schema MongoDB originale. Non è l'ideale, perché ogni volta che la logica per il campo calcolato cambia, dovrei fare aggiornamenti collettivi per aggiornare tutti i documenti della mia collezione, ma è stato quello o riscrivo il mio codice per usare MapReduce. Ho scelto il primo per ora. Guardando a bordo MongoDB Jira, sembrerebbe che molte persone hanno chiesto per gli operatori più diversificate da aggiungere per l'operatore $project e certamente spero che il team di sviluppo MongoDB ottiene intorno ad aggiungere loro prima che poi

Operator for splitting string based on a separator.

New projection operator $elemMatch

Allow $slice operator in $project

add a $inOrder operator to $project

Problemi correlati