We have been using the following command in MongoDB 2.4.* to create a field with auto-generated time-stamp values in inserted documents while not touching the same field for updates:
db.entity.update({EntityId : "ID01"},
{$setOnInsert : {Created : Timestamp(0,0)}, $set : {Name: "Abc"}},
{upsert : true})
This did work fine in 2.4.* with the inserted document having the field populated with the current time-stamp value:
{
"_id" : ObjectId("54e312dc649bb37cf4ab413a"),
"Created" : Timestamp(1424167644, 1),
"Name" : "Abc",
"EntityId" : "ID01"
}
However, when we run the same command in MongoDB 2.6.7, we end up with an empty time stamp:
{
"_id" : ObjectId("54e312e712e476107488a632"),
"EntityId" : "ID01",
"Created" : Timestamp(0, 0),
"Name" : "Abc"
}
Is there a way to reproduce 2.4 behavior in 2.6?
Related
So this is my data in mongodb
{
"_id" : ObjectId("60f67dc955784b233692a0f2"),
"Id" : "9153",
"InfoList" : [
{
"itemId" : "42342",
"price" : 1009.0,
"date" : ISODate("2021-01-01T08:30:36.131Z")
}
]
}
{
"_id" : ObjectId("6105668a55784bd00ef3ebc6"),
"Id" : "894249",
"InfoList" : [
{
"itemId" : "42342",
"price" : 23.0,
"date" : ISODate("2021-01-01T08:30:36.131Z")
},
{
"itemId" : "3221",
"price" : 44554.0,
"date" : ISODate("2013-07-31T15:05:10.042Z")
}
]
}
I want to find all the items in InfoList for all the documents whose date is less than 2021-02-09 and then delete them.
This is the code that I am using
Query query = new Query();
query.addCriteria(Criteria.where("InfoList")
.elemMatch(Criteria
.where("date")
.lte(date)));
return mongoTemplate.findAllAndRemove(query,ProductInfo.class, CollectionName);
But this code is neither finding the documents which have date < 2021-02-01 nor deleting them. Any suggestions regarding what might be wrong here ?
I'm not familiar with Mongo query I know mongoose more
But do it like this 1-get all the of the object
It will return an array
On this array
2-do an if to check if the date is less than 2021-02-09 if yes remove it using its id
Context:
Spring Data MongoDB is used and updating a document caused the following issue.
Issue :
After an update operation performed, document in collection lost all the data and kept only ObjectId in it.
Checking the oplog entry found an unusual value, understand that the o2field ObjectId says the object to be updated and ofield says about operations being performed/updated.
In this particular instance o2field has the expected value, but o field also has the same value instead of the update operation details to be done.
Question :
Any idea when can we expect such an oplog as mentioned below without $set or $unset for update operations ?
After this operation, actual document with ObjectId in collection lost all the fields except ObjectId.
{
"ts" : Timestamp(1596778564, 9),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "u",
"ns" : "db.collectionName",
"ui" : UUID("2947862a-8fb7-4342-87d1-a0ab5f8bc0bd"),
"o2" : {
"_id" : ObjectId("5f27e94e0174081a3feb5c6b")
},
"wall" : ISODate("2020-08-07T05:36:04.402Z"),
"lsid" : {
"id" : UUID("cbd4b90f-1bff-4ad1-b4e2-4c286fc25450"),
"uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
},
"txnNumber" : NumberLong(1269),
"stmtId" : 0,
"prevOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"o" : {
"_id" : ObjectId("5f27e94e0174081a3feb5c6b")
}
}
The update oplog for the same object few milliseconds ago is given below. Which has the right set of operations.
{
"ts" : Timestamp(1596778564, 8),
"t" : NumberLong(7),
"h" : NumberLong(0),
"v" : 2,
"op" : "u",
"ns" : "db.collectionName",
"ui" : UUID("2947862a-8fb7-4342-87d1-a0ab5f8bc0bd"),
"o2" : {
"_id" : ObjectId("5f27e94e0174081a3feb5c6b")
},
"wall" : ISODate("2020-08-07T05:36:04.398Z"),
"lsid" : {
"id" : UUID("cbd4b90f-1bff-4ad1-b4e2-4c286fc25450"),
"uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
},
"txnNumber" : NumberLong(1268),
"stmtId" : 0,
"prevOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"o" : {
"$v" : 1,
"$set" : {
.....
.......
......... //All the values to be updated
}
}
}
Hope it helps some one facing in Spring-MongoDB as well, as I did.
Tried following code, It happens when update used in mongoTemplate.updateFirst isn't set with any value while calling. If the line update.set is uncommented works fine. When nothing is set in update, it took it as replacement document.
#Override
public void run(String... args) throws Exception {
customerRepository.deleteAll();
customerRepository.save(new Customer("Bob","S"));
customerRepository.save(new Customer("Alice","Smith"));
findAll();
Update update = new Update();
// update.set("firstName", "Bobby");
Query query = Query.query(Criteria.where("lastName").is("S"));
mongoTemplate.updateFirst(query, update, "customer");
findAll();
}
Further checking our code, found that set is called on an update based on CONDITION IF values to set are available or not, it seems to working fine as long as the values are available and set is called on update. If the values are not available to set, set is not called on Update to set the values, which took it as replacement and replaced the entire document in collection.
One of your applications is providing a "replacement document" as described in https://docs.mongodb.com/manual/reference/method/db.collection.update/. The replacement document consists of the _id only which removes the other fields. There is nothing out of ordinary about the oplog entry you quoted.
Embedded Update query works fine in mlab and atlas but not working in Cosmos DB:
My Collection structure:
{
"_id" : ObjectId("5982f3f97729be2cce108785"),
"password" : "$2y$10$F2P9ITmyKNebpoDaQ1ed4OxxMZSKmKFD9ipiU1klqio239c/nJcme",
"nin" : "123",
"login_status" : 1,
"updated_at" : ISODate("2017-05-16T09:09:03.000Z"),
"created_at" : ISODate("2017-05-16T06:08:47.000Z"),
"files" : [
{
"name" : "abc",
"updated_at" : ISODate("2017-05-16T06:08:48.000Z"),
"created_at" : ISODate("2017-05-16T06:08:48.000Z"),
"_id" : ObjectId("5982f3f97729be2cce108784")
}
],
"name" : "demo",
"email" : "email#gmail.com",
"phone" : "1231234",
}
My query is:
db.rail_zones.update(
{'_id': ObjectId("5982f3f97729be2cce108785"),
'files._id' : ObjectId("5982f3f97729be2cce108784")},
{ $set: {'files.$.name' : "Changed"}})
I get this response:
"acknowledged" : true,
"matchedCount" : 0.0,
"modifiedCount" : 0.0
According to your description, I tested this issue on my side and found the Array Update could not work as expected. I assumed that the Array Update feature has not been implemented in the MongoDB Compatibility layer of Azure CosmosDB. Moreover, I found a feedback Positional array update via '$' query support talking about the similar issue.
Embedded Update query works fine in mlab and atlas but not working in Cosmos DB:
My Collection structure:
{
"_id" : ObjectId("5982f3f97729be2cce108785"),
"password" : "$2y$10$F2P9ITmyKNebpoDaQ1ed4OxxMZSKmKFD9ipiU1klqio239c/nJcme",
"nin" : "123",
"login_status" : 1,
"updated_at" : ISODate("2017-05-16T09:09:03.000Z"),
"created_at" : ISODate("2017-05-16T06:08:47.000Z"),
"files" : [
{
"name" : "abc",
"updated_at" : ISODate("2017-05-16T06:08:48.000Z"),
"created_at" : ISODate("2017-05-16T06:08:48.000Z"),
"_id" : ObjectId("5982f3f97729be2cce108784")
}
],
"name" : "demo",
"email" : "email#gmail.com",
"phone" : "1231234",
}
My query is:
db.rail_zones.update(
{'_id': ObjectId("5982f3f97729be2cce108785"),
'files._id' : ObjectId("5982f3f97729be2cce108784")},
{ $set: {'files.$.name' : "Changed"}})
I get this response:
"acknowledged" : true,
"matchedCount" : 0.0,
"modifiedCount" : 0.0
According to your description, I tested this issue on my side and found the Array Update could not work as expected. I assumed that the Array Update feature has not been implemented in the MongoDB Compatibility layer of Azure CosmosDB. Moreover, I found a feedback Positional array update via '$' query support talking about the similar issue.
I have a document and I need to query mongodb database to return me all the documents which was inserted after current document.
Is it possible and how to do that query?
If you do not override the default _id field you can use that objectID (see the mongodb docs) to make a comparison by time. For instance, the following query will find all the documents that are inserted after curDoc has been inserted (assuming none overwrite the _id field):
>db.test.find({ _id : {$gt : curDoc._id}})
Note that these timestamps are not super granular, if you would like a finer grained view of the time that documents are inserted I encourage you to add your own timestamp field to the documents you are inserting and use that field to make such queries.
If you are using Insert time stamp as on of the parameter, you can query like below
> db.foo.find()
{ "_id" : ObjectId("514bf8bbbe11e483111af213"), "Name" : "abc", "Insert_time" : ISODate("2013-03-22T06:22:51.422Z") }
{ "_id" : ObjectId("514bf8c5be11e483111af214"), "Name" : "xyz", "Insert_time" : ISODate("2013-03-22T06:23:01.310Z") }
{ "_id" : ObjectId("514bf8cebe11e483111af215"), "Name" : "pqr", "Insert_time" : ISODate("2013-03-22T06:23:10.006Z") }
{ "_id" : ObjectId("514bf8eabe11e483111af216"), "Name" : "ijk", "Insert_time" : ISODate("2013-03-22T06:23:38.410Z") }
>
Here my Insert_time corresponds to the document inserted time, and following query will give you the documents after a particular Insert_time,
> db.foo.find({Insert_time:{$gt:ISODate("2013-03-22T06:22:51.422Z")}})
{ "_id" : ObjectId("514bf8c5be11e483111af214"), "Name" : "xyz", "Insert_time" : ISODate("2013-03-22T06:23:01.310Z") }
{ "_id" : ObjectId("514bf8cebe11e483111af215"), "Name" : "pqr", "Insert_time" : ISODate("2013-03-22T06:23:10.006Z") }
{ "_id" : ObjectId("514bf8eabe11e483111af216"), "Name" : "ijk", "Insert_time" : ISODate("2013-03-22T06:23:38.410Z") }
>