2017-09-10 1 views
0

Habituellement, j'évite de poser une nouvelle question car je trouve toujours une réponse «assez proche» à mon problème.MongoDB met à jour un élément de tableau dans un index spécifique en utilisant le pilote Java

Mais cette fois j'ai étonnamment une question fondamentale et directe - sans aucun plomb.

J'ai un document MongoDB simple qui contient deux tableaux:

  • Le 1er contenant trois numéros (ints) - représentent chacun un numéro de code d'une question sélectionnée (prédéfinie). Le 2nd contenait 3 Strings - ce sont les réponses données par l'utilisateur à ces trois questions correspondantes.

Par exemple, disons que sujet le code 12 est - « Quelle est votre 1er nom du chien? » Et la réponse de l'utilisateur était: « hérissés », etc ...

Alors je me retrouve avec quelque chose comme:

{ 
     "_id" : ObjectId("..."), 
     "questionCodesArray" : [ 
       12, 
       56, 
       3 
      ], 
     "answersArray" : [ 
       "Spiky", 
       "go swimming", 
       "blabla.." 
      ] 
    } 

maintenant, je voudrais être en mesure de permettre aux utilisateurs de changer leur esprit et choisir une autre question et fournir une réponse différente à elle.

Pour cela, je dois avoir que l'indice de mon élément et l'accès via cet indice pour le changer en utilisant update() ou findAndModify() [ou toute autre méthode] et toutes les réponses sont là-bas « Key- style de valeur "qui n'est pas nécessaire.

Dans Java simple, je l'aurais fait tout simplement quelque chose comme:

questionsCodesArry[index] = newValue; et answersArray[index] = newAnswerString;

Toutes mes tentatives d'écrire une requête de descente pour faire cette simple mise à jour indicielle ont échoué.

Toute aide sera appréciée.

Merci.

+0

Il devrait être plus facile à maintenir si vous avez un tableau qui se fonde à la fois les questions et les réponses – barbakini

Répondre

0

Dans la syntaxe MongoDB clairement ce dont vous avez besoin est ceci:

collection.update({ 
    /*your filter goes here*/ 
}, { 
    $set: { 
     "questionCodesArray.<zero-based-index>": "new value" 
    } 
}) 

Je n'ai pas un environnement Java ici pour traduire dans le monde de conduire. Je pourrais être en mesure de le faire ce soir, cependant.

encore, je serais certainement voter pour un autre, une conception plus naturelle et moins sujette aux erreurs où vous souhaitez structurer vos données comme ceci:

{ 
    "_id" : ObjectId("59b635ffad44fad6662d8591"), 
    "answers" : [ 
     { 
      "questionCode" : 12, 
      "answer" : "Spiky" 
     }, 
     { 
      "questionCode" : 56, 
      "answer" : "go swimming" 
     }, 
     { 
      "questionCode" : 3, 
      "answer" : "blabla.." 
     } 
    ] 
} 

Si c'est une option pour vous je heureux de vous fournir la bonne instruction de mise à jour pour cette mise en page, aussi.

+0

Salut sans faute et merci pour votre réponse. Je suis d'accord sur votre commentaire concernant la structure du tableau et apporterai les modifications appropriées. – JamesC

+0

Mais comme vous pouvez le deviner, la question est d'avoir un accès basé sur un index pour les éléments de tableaux. Donc, à partir de votre commentaire, je devine que le code Java à ceci est quelque chose comme: 'DBObject update = new BasicDBObject (" $ set ", nouveau BasicDBObject (" questionCodesArray.1 ", newValue));'? Pouvez-vous fournir un code de travail complet? – JamesC

+0

Oui, je pourrais, mais je pars à Madrid dans quelques minutes et seulement de retour lundi. Alors sois indulgent avec moi. – dnickless

0

Eh bien, après quelques essais ici est ac & p méthode complète et complète pour changer l'élément d'un tableau par un index donné:

public boolean changeArrayValue(DB db, String collectionName, long id, String arrayNameKey, int index, Object newValue) 
{ 
    DBCollection collection = db.getCollection(collectionName); 
    DBObject query   = new BasicDBObject("id",id);//unique id is recommended 
    DBObject update   = new BasicDBObject("$set", new BasicDBObject(arrayNameKey+"."+index, newValue)); 

    DBObject result = collection.findAndModify(query, null, null, false, update,true, true); 

    //Just for precaution 
    if(result == null) 
     return false; 

    return (((BasicDBList)result.get(arrayNameKey)).get(index)).equals(newValue); 
} 

Comme vous pouvez le voir la question principale réside dans la ligne $set ici: arrayNameKey+"."+index .

Dans le résultat, j'ai mis les drapeaux nécessaires pour obtenir le résultat mis à jour, qui est de type BasicDBList<Object>.

Veuillez noter que vous devrez ajouter tous les contrôles et validations nécessaires selon vos goûts. Profitez ..