I have the following objects in my mongo db:
{
"type" : "timetype"
"time" : "18"
}
{
"type" : "timetype"
"time" : "5"
}
{
"type" : "timetype"
"time" : "43"
}
{
"type" : "timetype"
"time" : "23"
}
And my java code looks like:
BasicDBObject query = new BasicDBObject();
query.put("type", "timetype");
//I don't know what to put in the (...)
DBCursor cursor = Collection.find(query).sort(...).limit(1);
I would like to find the entry with the smallest time in my mongo database that meets the query parameter but I don't know what to put in sort to make that happen.
Something along the lines of
Collection.find(query).sort(new BasicDBObject( "time" , 1 )).limit(1);
should work.
Related
I've been working with mongo for a few months and I'm struggling now.
Here is a document example of my database:
"_id" : ObjectId("5732d96fed40761e640a3f3e"),
"_familyId" : "12345",
"_applications" : [
{
"_applicationRID" : "123456",
"_applicationDate" : "01012000",
"_isRepresentative" : false,
"_applicationId" : {
"CC" : "AB",
"SN" : "123456789",
"KC" : "A"
},
"_publications" : [
{
"_publicationRID" : "123456789",
"_publicationDate" : "01012000",
"_flaId" : "AB123456789A",
"_publicationId" : {
"CC" : "AB",
"SN" : "1234567",
"KC" : "B"
},
[...]
Now, I'm trying to do a collection.find() in Java on an array.
I know all the fields contained in _publicationId and I need to search on _publicationId because it has an index but not the fields inside it.
In shell it would be:
db.collection.find({
"_applications._publications._publicationId": {
"CC": "AB",
"SN": "1234567",
"KC": "B"
}
})
and this works fine.
Using java, I can't find the proper syntax:
collection.find("_applications._publications._publicationId", ??? )
You should try with a query of the next type that is actually the exact equivalent of your query in java:
DBObject query = new BasicDBObject(
"_applications._publications._publicationId",
new BasicDBObject("CC", "AB").append("SN", "1234567").append("KC", "B")
);
DBCursor cursor = collection.find(query);
I want to retrieve id of a record in mongodb collection by specifying the name.
That's what I tried by it returned the whole thing, but I just want the id. Any help?
DBCollection parameterTable = db.getCollection("configurationTable");
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("name", "data1");
DBCursor cursor = parameterTable.find(searchQuery);
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
And that's what it returns:
{ "_id" : { "$oid" : "5423d3ceccf213e6d265fc9c"} , "name" : "data1" , "created" : { "$date" : "2014-09-25T08:35:26.361Z"} , "timestamp" : { "$date" : "2014-09-25T08:35:26.361Z"}}
I'm not much sure, yet to get the id you can do something like :
cursor.next().get("_id");
I've this document:
{
"_id" : ObjectId("54140782b6d2ca6018585093"),
"user_id" : ObjectId("53f4ae1ae750619418a20467"),
"date" : ISODate("2014-09-13T08:59:46.709Z"),
"type" : 0,
"tot" : 2,
"additional_info" : {
"item_id" : ObjectId("540986159ef9ebafd3dcb5d0"),
"shop_id" : ObjectId("53f4cc5a6e09f788a103d0a4"),
"ap_id" : ObjectId("53f4cc5a6e09f788a103d0a5")
},
"transactions" : [
{
"_id" : ObjectId("54140782b6d2ca6018585091"),
"date_creation" : ISODate("2014-09-13T08:59:46.711Z"),
"type" : -1
},
{
"_id" : ObjectId("54140782b6d2ca6018585092"),
"date_creation" : ISODate("2014-09-13T08:59:46.788Z"),
"type" : 1
}
]
}
and I need to add 2 more field to the first transaction opbject:
- date_execution: date
- result: this bson document
{ "server_used" : "xxx.xxx.xxx.xxx:27017" , "ok" : 1 , "n" : 1 , "updated_executed" : true} (m_OR.getDocument() in the following code example)
to obtaing that document
{
"_id" : ObjectId("54140811b6d25137753c1a1a"),
"user_id" : ObjectId("53f4ae1ae750619418a20467"),
"date" : ISODate("2014-09-13T09:02:09.098Z"),
"type" : 0,
"tot" : 2,
"additional_info" : {
"item_id" : ObjectId("540986159ef9ebafd3dcb5d0"),
"shop_id" : ObjectId("53f4cc5a6e09f788a103d0a4"),
"ap_id" : ObjectId("53f4cc5a6e09f788a103d0a5")
},
"transactions" : [
{
"_id" : ObjectId("54140811b6d25137753c1a18"),
"date_creation" : ISODate("2014-09-13T09:02:09.100Z"),
"type" : -1,
"result" : {
"server_used" : "xxx.xxx.xxx.xxx:27017",
"ok" : 1,
"n" : 1,
"updated_executed" : true
},
"date_execution" : ISODate("2014-09-13T09:02:15.370Z")
},
{
"_id" : ObjectId("54140811b6d25137753c1a19"),
"date_creation" : ISODate("2014-09-13T09:02:09.179Z"),
"type" : 1
}
]
}
The only way I was able to do that is the do 2 separates updates (update is a my wrapper funciont that execute the real updates in mongodb and it works fine):
// where
BasicDBObject query = new BasicDBObject();
query.append("transactions._id", m_Task.ID());
// new value for result - 1st upd
BasicDBObject value = new BasicDBObject();
value.put("$set",new BasicDBObject("transactions.$.date_execution",new Date()));
update(this._systemDB, "activities", query, value);
// new value for date_execution - 2nd upd
value = new BasicDBObject();
value.put("$set",new BasicDBObject("transactions.$.result",m_OR.getDocument()));
update(this._systemDB, "activities", query, value);
If I try to do this:
BasicDBObject value = new BasicDBObject();
value.put("$set",new BasicDBObject("transactions.$.date_execution",new Date()));
value.put("$set",new BasicDBObject("transactions.$.result",m_OR.getDocument()));
or = update(this._systemDB, "activities", query, value);
just the 2nd set will be applied.
Is there any way do avoid the double execution and apply the update with just one call?
Basic rule of "hash/map" objects is that you can only have one key. It's the "highlander" rule ( "There can be only one" ) applied in general reason. So just apply differently:
BasicDBObject value = new BasicDBObject();
value.put("$set",
new BasicDBObject("transactions.$.date_execution",new Date())
.add( new BasicDBObject("transactions.$.result",m_OR.getDocument() )
);
So basically "both" field arguments are part of the "$set" statement as in the serialized form:
{
"$set": {
"transactions.$.date_execution": new Date(),
"transactions.$.result": m_Or.getDocument()
}
}
Which is basically what you want in the end.
Your suggestion was right, just had to fix a little the syntax this way:
BasicDBObject value = new BasicDBObject();
value.put("$set",
new BasicDBObject("transactions.$.date_execution",new Date())
.append("transactions.$.result",m_OR.getDocument())
);
This worked perfectly ;)
Thanks!
Samuel
So I have a few dbobjects in my mongo database. Here's an example of one of the objects:
{ "_id" : { "$oid" : "525b048580c3fb0d62d2b6fc"} , "city" : "London" , "currentWeather" : [ { "cloudcover" : "25" , "humidity" : "82" , "observation_time" : "08:37 PM" , "precipMM" : "0.0" , "pressure" : "1008" , "temp_C" : "11" , "temp_F" : "52" , "visibility" : "10" , "weatherCode" : "113" , "weatherDesc" : [ { "value" : "Clear"}] , "weatherIconUrl" : [ { "value" : "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0008_clear_sky_night.png"}] , "winddir16Point" : "W" , "winddirDegree" : "280" , "windspeedKmph" : "19" , "windspeedMiles" : "12"}]}
Now, I need to get all the dbobjects in my database whose value is lower than a given "temp_C", I have used something like this:
BasicDBObject query = new BasicDBObject("temp_C", new BasicDBObject(">", graden));
But it's failing, and I think it is because the property is a subproperty of "currentWeather", yet I have no idea how to address this problem. I am using java to do this.
Looking at your document structure, you're trying to access a subdocument that lives inside an array in your document, so it's a bit more complicated than a standard query:
{ "_id" : { "$oid" : "525b048580c3fb0d62d2b6fc"} , <-- Document
"city" : "London" ,
"currentWeather" : [ <-- Array
{ "cloudcover" : "25", <-- Sub document
...etc...
"pressure" : "1008" ,
"temp_C" : "11",
"temp_F" : "52",
...etc...
}
]
}
In order to get to the nested object, you need to reference its position in the array (in this case, it's zero as it's the first element in the array) and then the field name in the sub document. So your query looks like this:
BasicDBObject query = new BasicDBObject("currentWeather.0.temp_C",
new BasicDBObject("$gt", 11));
Note you had two problems in your original query:
1) You need to reference currentWeather.0.temp_C
2) Your gt operator needs to start with a dollar sign not an ampersand.
Also, you said you wanted the query to return values lower than a given value, in which case you probably want $lt not $gt.
You can't directly use the value of the object of an array in a query. You can use aggregate framework of Mongo. Java Docs For Aggregate are here
I have a little bug with my script:
BasicDBObject change = new BasicDBObject();
BasicDBObject account =
new BasicDBObject().append("$set", new BasicDBObject().append("status", 0));
account.append("pos.X", getX());
account.append("pos.Y", getY());
account.append("pos.Z", getZ());
change.append("pseudo", gPlayer);
coll.update(change, account);
And the structure of mongoDB is :
{
pseudo: "pseudo"
email: "email"
password: "password"
status: "1"
pos: [
{X: "90.45}
{Y: "90.45}
{Z: "90.45}
]
}
But this is not working! No value is modified.
Thanks for your help.
Java is a very verbose language, and sometimes it is easiest to first write your query using the JS shell, make sure it performs as desired, and then translate it into Java.
By adding System.out.println(account.toString()) to your Java code, I can see that your Update document looks like the following, which is not valid:
{ "$set" : { "status" : 0} , "pos.X" : "90.45" , "pos.Y" : "90.45" , "pos.Z" : "90.45"}
From your question, it is not entirely clear what you would like your updated document to look like, but I am guessing that you would like to modify the values of "status" and "pos.0.X", "pos.1.Y", and "pos.2.Z". Because X, Y, and Z are all stored as individual embedded documents inside an array, they will have to be referenced by their positions in order to be updated at the same time. If possible, you might find it preferable to rearrange your document structure such that X, Y, and Z are all stored inside the same document, like so:
"pos" : {
"X" : "0",
"Y" : "0",
"Z" : "0"
}
This way, you will be able to access each variable more easily using dot notation, pos.X, pos.Y, pos.Z, which from your post looks like what you were intending. More information on embedded documents may be found in the "Dot Notation (Reaching into Objects)" documentation:
http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
Here is an Update statement that will modify the above values:
> db.pseudo.find({ "pseudo" : "gPlayer"}).pretty()
{
"_id" : ObjectId("4f904ebb5bebd4375b759c90"),
"email" : "email",
"password" : "password",
"pos" : [
{
"X" : "90.45"
},
{
"Y" : "90.45"
},
{
"Z" : "90.45"
}
],
"pseudo" : "gPlayer",
"status" : "1"
}
> db.pseudo.update({"pseudo" : "gPlayer"}, { "$set" : { "status" : 0 , "pos.0.X" : "0" , "pos.1.Y" : "0" , "pos.2.Z" : "0"}})
> db.pseudo.find({ "pseudo" : "gPlayer"}).pretty()
{
"_id" : ObjectId("4f904ebb5bebd4375b759c90"),
"email" : "email",
"password" : "password",
"pos" : [
{
"X" : "0"
},
{
"Y" : "0"
},
{
"Z" : "0"
}
],
"pseudo" : "gPlayer",
"status" : 0
}
>
Translated into Java this is:
BasicDBObject change = new BasicDBObject("pseudo", "gPlayer");
BasicDBObject setDoc = new BasicDBObject();
setDoc.append("status", "0");
setDoc.append("pos.0.X", "0");
setDoc.append("pos.1.Y", "0");
setDoc.append("pos.2.Z", "0");
BasicDBObject account = new BasicDBObject("$set", setDoc);
coll.update(change, account);
I realize that I guessed a little bit about exactly the update that you would like to do, but hopefully the above will get you pointed in the right direction!