adam
adam

Reputation: 978

issue with $inc operator & java driver

I'm getting this error: Document field names can't start with '$' (Bad Key: '$inc') with this code:

private static void countryInc(String user_id, String country, BasicDBObject doc, DBCollection dBcollection, Integer count ) throws IOException {

    DBObject fromDBobject = new BasicDBObject();        
    DBObject countryDBobject = new BasicDBObject();
    countryDBobject.put(country, count);
    fromDBobject.put("user_id", user_id);
    fromDBobject.put("countries", countryDBobject);

    DBObject toDBobject = new BasicDBObject();
    DBObject ccDBObject = new BasicDBObject(country, 1);
    DBObject incdbobject = new BasicDBObject("$inc", ccDBObject);
    toDBobject.put("user_id", user_id);
    toDBobject.put("countries", incdbobject);

    dBcollection.update(fromDBobject, toDBobject);          
}

this is a sample of what my db looks like:

{ 
    "_id" : { 
        "$oid" : "53b56ccb1ac175a446cf244f"
    },
    "user_id" : "7778", 
    "countries": { "JA" : 1}
}
{ 
    "_id" : { 
        "$oid" : "53b56ccb1ac175a446cf2450"
    }, 
    "user_id" : "4657",
    "countries" : { "TU" : 1}
}
{ 
    "_id" : { 
        "$oid" : "53b56ccb1ac175a446cf2451"
    }, 
    "user_id" : "5918",
    "countries" : { "BR" : 1}
}

I'm at a loss as to why this won't increment the count for each country every time that a user_id is seen.

Upvotes: 0

Views: 821

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151122

Debugging and logging really is your friend dear padawan. You should always dump the serializations of what you are trying to do. Here is what your fromDBObject and toDBObject items look like from a dump:

// from
{ "user_id" : 7778 , "countries" : { "JA" : 1} }
// to
{ "user_id" : 7778 , "countries" : { "$inc" : { "JA" : 1} } }

A quick peruse of the general documentation should show you that is not remotely close to a valid update statement with the "update" document portion.

You need the $inc side there to be on the other side of the field you are updating, and the user_id part is really not needed. Aside from this, you need to be using "dot notation" as this is the much more simplified and more accurate way of forming your query.

For me, the basic "query" and "update" parts of the statement are formed like this:

    DBObject query = new BasicDBObject(
        "user_id", 7778
    ).append(
        "countries.JA", 1
    );

    DBObject update = new BasicDBObject(
        "$inc", new BasicDBObject("countries.JA", 1)
    );

    System.out.println("//query:\n" + query);
    System.out.println("//update:\n" + update);

Very simple serialize:

//query:
{ "user_id" : 7778 , "countries.JA" : 1}
//update:
{ "$inc" : { "countries.JA" : 1}}

Which I am sure when you consult the documentation, you will then find that is how the statements should be formed.

Upvotes: 1

Related Questions