简体   繁体   English

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

[英]MongoDB updating an array element in a specific index using the Java driver

Usually, I avoid asking a new question as I always find a "close-enough" answer to my problem. 通常,我避免提出新的问题,因为我总是能找到一个“足够接近”的答案。

But this time I surprisingly have a fundamental and straightforward question - without any lead. 但这一次,我令人惊讶地提出了一个基本而直接的问题-没有任何线索。

I have a straightforward MongoDB document that holds two arrays: 我有一个简单的MongoDB文档,其中包含两个数组:

  • The 1st containing three numbers (ints) - each represent a code-number of a selected (predefined) question. 第一个包含三个数字(int)-每个数字代表一个选定(预定义)问题的代码号。

  • The 2nd was holding 3 Strings - that are the answers given by the user to these three correspondent questions. 第二个持有3个字符串-用户对这三个对应问题给出的答案。

For example, let's say subject code 12 is - "What's your 1st dog's name?", and the user's answer was: "Spiky", etc... 例如,假设主题代码12是-“您的第一只狗叫什么名字?”,而用户的回答是:“尖锐”,等等。

So I end up with something like: 所以我最终得到这样的东西:

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

Now, I'd like to be able to allow the users to change their mind and choose a different question and supply a different answer to it. 现在,我希望能够允许用户改变主意,选择其他问题并提供不同的答案。

For this, I need to have only the index of my element and access it via this index to change it using update() or findAndModify() [or any other method] and all the answers out there are "key-value style" which is not needed. 对于这一点,我需要有只我的元素的索引 ,并改变使用它通过这个索引来访问它update()findAndModify() [或任何其他方法],所有的答案排除有“键值风格”,这不需要。

In simple Java I would've simply done something like: 在简单的Java中,我将简单地执行以下操作:

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

All my attempts to write a descent query to do this simple index-based updating have failed. 我编写下降式查询以执行此简单的基于索引的更新的所有尝试均失败了。

Any help will be appreciated. 任何帮助将不胜感激。

Thank you. 谢谢。

In plain MongoDB syntax what you need is this: 用简单的MongoDB语法,您需要的是:

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

I don't have a Java environment here to translate this into your driver's world. 我这里没有Java环境,无法将其转换为驱动程序的世界。 I might be able to do so tonight, though. 不过,今晚我也许可以这样做。

Still, I would definitely vote for a different, more natural and less error-prone design where you'd structure your data like so: 尽管如此,我绝对会投票支持另一种更自然,更不易出错的设计,在这种设计中,您可以像这样构造数据:

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

If that's an option for you I shall happily provide you the right update statement for this layout, too. 如果您愿意这样做,我也会很高兴为您提供此布局的正确更新声明。

Well, after some trials here is a c&p complete and full method to change an array's element by a given index: 好吧,经过一番尝试之后,这里提供了一种c&p完整完整方法,可以通过给定索引更改数组的元素:

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

As you can see the main issue lays in the $set line here: arrayNameKey+"."+index . 如您所见,主要问题在于此处的$set行: arrayNameKey+"."+index

In the result I've put the needed flags to get the updated result, which is of type BasicDBList<Object> . 在结果中,我放置了需要的标志以获取更新的结果,该结果的类型为BasicDBList<Object>

Pleases note that you'll have to add all the needed checks and validations according to your taste. 请注意,您必须根据自己的喜好添加所有必需的检查和确认。 Enjoy.. 请享用..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM