2012-05-27 8 views
8

Estoy tratando esto en el mongodb console:

db.foobar.update( 
    { name: "Foobar" }, 
    { 
    $set : { foo: { bar: 'bar' }, 
    $inc: { 'foo.count': 1 } 
    } 
}, true) 

Vuelve con "OK", pero db.foobar.find(), devuelve un conjunto de registros vacío. Estoy tratando de upsert un documento, por lo que parece el:

name: Foobar 
foo: { 
    bar: 'bar' 
    count: 1 
} 

Si no existe el documento a continuación, crear una con un conteo de 1. De lo contrario, simplemente aumentar la cuenta. ¿Por qué no está arriba trabajando?

Respuesta

7

Me parece que su código realmente intenta establecer el campo $ inc del documento en lugar de usar el modificador $ inc en el campo foo.count. Esto podría ser lo que desea:

db.foobar.update(
    { name: "Foobar" }, 
    { 
     $set: { 'foo.bar': 'bar' }, 
     $inc: { 'foo.count': 1 } 
    }, true) 

Espero que esto ayude.

+0

Eso funciona. Pero por qué esto no funciona: 'db.foobar.update ({name:" Foobar "}, {$ set: {foo: {bar: 'bar'}}, $ inc: {'foo.count': 1 }}, true) 'Parece que establecer una cadena lo hará funcionar. Pero me pregunto por qué –

+1

¡No me había dado cuenta de eso! El mensaje de error proporcionado por el shell es 'tiene modificaciones conflictivas en la actualización'. Para mí, esto sugiere que $ set opera en el subdocumento 'foo' como un todo, por lo tanto, no puede usar $ inc en 'foo' o cualquiera de sus propiedades, como 'foo.count'. Conjeturo que usar $ set en 'foo.bar' y $ inc en 'foo.count' funciona porque los dos modificadores apuntan a partes disjuntas del documento. – idrarig

1

En el fragmento de código que proporcionó, falta un cierre de cierre después del objeto $ set. Pero ese es un problema secundario.

No creo que pueda establecer e incrementar el mismo documento secundario en una transacción. Como count es miembro de foo, en una inserción, todavía no existirá. El error que recibo cuando intento lo siguiente:

db.foobar.update( 
    { name: "Foobar" }, 
    { 
    $set : { foo: { bar: 'bar' }}, 
    $inc: { 'foo.count': 1 } 
    } 
}, true) 

es "modificaciones conflictivas en la actualización". Tal vez se puede modelar de esta manera:

db.foobar.update({name:"foobar"},{$set:{foo:{bar:"bar"}},$inc:{count:1}},true); 

o si lo prefiere:

db.foobar.update({name:"foobar"},{$set:{foo:{bar:"bar"}},$inc:{"counts.foo":1}},true); 
0

Así que estoy actualmente tratando:

var doc = { 
      "name": "thename", 
      "organisation": "theorganisation" 
     }, // document to update. Note: the doc here matches the existing array 
    query = { "email": "[email protected]" }; // query document 
    query["history.name"] = doc.name; // create the update query 
    query["history.organisation"] = doc.organisation; 
    var update = db.getCollection('users').findAndModify({ 
     "query": query, 
     "update": { 
      "$set": { 
       "history.$.name": doc.name, 
       "history.$.organisation": doc.organisation 
      }, 
      "$inc": { "history.$.score": 5 } //increment score 
     } 
    }); 
    if (!update) { 
     db.getCollection('users').update(
      { "email": query.email }, 
      { "$push": { "history": doc } } 
     ); 
    } 
    db.getCollection('users').find({ "email": "[email protected]" }); 

Esto actualiza el score, y lo añade al objeto si no existe, sin embargo, parece cambiar todos los objetos name s a doc.name (es decir, "thename" en este caso).

No he llegado si el documento aún no existe

Cuestiones relacionadas