MongoDB使用Java驱动程序更新特定索引中的数组元素

时间:2017-09-10 16:00:05

标签: java arrays mongodb indexing

通常,我会避免提出一个新问题,因为我总能找到一个“足够接近”的问题答案。

但这次我出乎意料地有一个基本而直截了当的问题 - 没有任何领导。

我有一个简单的MongoDB文档,它包含两个数组:

  • 第一个包含三个数字(整数) - 每个代表一个选定(预定义)问题的代码编号。

  • 第二个持有3个字符串 - 这是用户对这三个相关问题的答案。

例如,让我们说主题代码12是 - “你的第一只狗的名字是什么?”,用户的回答是:“Spiky”等......

所以我最终得到了类似的东西:

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

现在,我希望能够允许用户改变主意并选择不同的问题并提供不同的答案。

为此,我需要只有我的元素的索引并通过此索引访问它,以使用update()或{{1}更改它} [或任何其他方法]并且所有答案都是“键值样式”,这是不需要的。

在简单的Java中,我会简单地完成以下操作:

findAndModify()questionsCodesArry[index] = newValue;

我尝试编写下降查询来执行这种简单的基于索引的更新失败了。

任何帮助将不胜感激。

谢谢。

2 个答案:

答案 0 :(得分:1)

在简单的MongoDB语法中,您需要的是:

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

我这里没有Java环境可以将其转换为您的驱动程序世界。不过我今晚也许能够这样做。

尽管如此,我肯定会投票支持一种不同的,更自然且不易出错的设计,你可以像这样构建数据:

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

如果这是您的选择,我也很乐意为您提供此布局的正确更新声明。

答案 1 :(得分:0)

嗯,经过一些试验后,这是一个完整且完整的方法来改变给定索引的数组元素:

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);
}

正如您所看到的,主要问题位于此处的$set行:arrayNameKey+"."+index

在结果中我放置了所需的标志来获取更新的结果,类型为BasicDBList<Object>

请注意,您必须根据自己的喜好添加所有必需的检查和验证。 享受..