Spring data mongodb check inside array whether value presents - mongodb

I want to fetch all documents in which readBy array has suppose "2" value using spring data API.
Please help me.
My JSON in Mongodb is like this.
{
"_id" : ObjectId("52c14eb92f7ceb854e445354"),
"attachments" : [{
"fileMongoId" : "52c14eb82f7ceb854e44534b",
"fileName" : "Desert.jpg",
"fileSize" : "0 MB",
"fileType" : "image/jpeg"
}, {
"fileMongoId" : "52c14eb82f7ceb854e445350",
"fileName" : "Hydrangeas.jpg",
"fileSize" : "0 MB",
"fileType" : "image/jpeg"
}],
"from" : NumberLong(2),
"fromName" : "xyz",
"hasAttachment" : true,
"message" : "Hi all\r\n",
"read" : 1,
"readBy" : ["2", "3"],
"sentTime" : NumberLong("1388400312645"),
"sentType" : 2,
"subject" : "Hi",
"to" : [{
"toId" : "3",
"toName" : "pqr"
}, {
"toId" : "2",
"toName" : "xyz"
}]
}
Code to generate query
Username is string which I want to check whether it is present in readBy array or not
readBy is array of String
Query query = new Query();
Update update = new Update();
Criteria criteria = new Criteria();
if (read) {
// criteria = Criteria.where(username).in("readBy");
query.addCriteria(criteria.andOperator(Criteria.where("to.toId")
.in(toIdList)));
} else {
// criteria = Criteria.where(username).nin("readBy");
update.addToSet("readBy", username);
query.addCriteria(criteria.andOperator(Criteria.where("to.toId")
.in(toIdList)));
mongoTemplate.updateMulti(query, update, NewMessage.class);
}
query.fields().include("from");
query.fields().include("fromName");
query.fields().include("sentTime");
query.fields().include("hasAttachment");
query.sort().on("sentTime", Order.DESCENDING);
newMessages = mongoTemplate.find(query, NewMessage.class);

Related

Mongoose updateMany :: wont find any on given condition

I have updateMany function as follows
Article.updateMany({author: userId}, {author: anonym}, function(err, updated) {
if (err) {
res.send(err);
} else {
res.send(updated);
}
});
userId is = 6068b57dbe4eef0b579120c7
anonym is = 6069870676d6320f39e7e5a2
for testing purposes I have a single article in MongoDB as follows
db.articles.find()
{ "_id" : ObjectId("6068b591be4eef0b579120c8"), "favoritesCount" : 1, "comments" : [ ], "tagList" : [ ], "title" : "Martin", "description" : "Testib", "body" : "Asju", "author" : ObjectId("6068b57dbe4eef0b579120c7"), "slug" : "martin-2hzx78", "createdAt" : ISODate("2021-04-03T18:36:01.977Z"), "updatedAt" : ISODate("2021-04-03T18:53:29.809Z"), "__v" : 0 }
You can see that article has "author" : id field in it which currently shows userId as author.
I want to update that field and transfer authorship to anonym user.
When I send this request to postman I get following response
{
"n": 0,
"nModified": 0,
"ok": 1
}
And database remains unchanged. What am I doing wrong here ?

Mongodb put Documents array as the same level

I have this array of documents, I would like to put "table" on the same level like mastil_antenas and other variables. how Can I do that with aggregate?
I'm trying with the aggregate $project but I can't get the result.
Example of Data
[ {
"mastil_antena" : "1",
"nro_platf" : "1",
"antmarcmast" : "ANDREW",
"antmodelmast" : "HWXXX6516DSA3M",
"retmarcmast" : "Ericsson",
"retmodelmast" : "ATM200-A20",
"distmast" : "1.50",
"altncramast" : "41.30",
"ORIENTMAG" : "73.00",
"incelecmast" : "RET",
"incmecmast" : "1.00",
"Feedertypemast" : "Fibra Optica",
"longjumpmast" : "5.00",
"longfo" : "100",
"calibrecablefuerza" : "10 mm",
"longcablefuerza" : "65.00",
"modelorruantena" : "32B66A",
"tiltmecfoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114934746000.jpg",
"tiltmecfoto_fh" : "2017-10-18T05:51:22Z",
"az0foto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115012727000.jpg",
"az0foto_fh" : "2017-10-18T05:55:21Z",
"azneg60foto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115016199000.jpg",
"azneg60foto_fh" : "2017-10-18T05:55:36Z",
"azpos60foto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115020147000.jpg",
"azpos60foto_fh" : "2017-10-18T05:55:49Z",
"etiqantenafoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114920853000.jpg",
"etiqantenafoto_fh" : "2017-10-18T05:56:01Z",
"tiltelectfoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114914236000.jpg",
"tiltelectfoto_fh" : "2017-10-18T05:56:13Z",
"idcablefoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114900279000.jpg",
"idcablefoto_fh" : "2017-10-18T05:56:38Z",
"rrutmafoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114947279000.jpg",
"rrutmafoto_fh" : "2017-10-18T05:56:49Z",
"etiquetarrufoto" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114954648000.jpg",
"etiquetarrufoto_fh" : "2017-10-18T05:57:02Z",
"rrutmafoto1" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017114959738000.jpg",
"rrutmafoto1_fh" : "2017-10-18T05:57:12Z",
"etiquetarrufoto1" : "https://secure.appenate.com/Files/FormEntry/47929-92cdf219-3128-4903-8324-a81000602b9d171017115005545000.jpg",
"etiquetarrufoto1_fh" : "2017-10-18T05:57:27Z",
"botontorre4" : "sstelcel3",
"table" : { /* put all varibles one level up*/
"tecmast" : "LTE",
"frecmast" : "2100",
"secmast" : "1",
"untitled440" : "Salir"
},
"comentmast" : "",
"longfeedmast" : "",
"numtmasmast" : "",
"otra_marca_antena" : "",
"otro_modelo_antena" : ""
}]
Starting from MongoDB version 3.4 you could use $addFields to do this.
//replace products with what makes sense in your database
db.getCollection('products').aggregate(
[
{ //1 add the properties from subdocument table to documents
$addFields: {
"documents.tecmast" : "documents.0.table.tecmast",
"documents.frecmast" : "documents.0.table.frecmast",
"documents.secmast" : "documents.0.table.secmast",
"documents.untitled440" : "documents.0.table.untitled440"
}
},
{
//(optional) 2 remove the table property from the documents
$project: {"documents.table" : 0}
}
]
)
Step 1: use $addFields to grab properties from table inside documents.table and put them on documents
Step 2: (optional) remove property "table" from documents.
I hope this helps!!!

How to aggregate values in an array of objects in MongoDB

I store documents from cars and want to get the temperature of all Mercedes cars as an array, how should the query be in Mongodb?
{ "_id" : { "$oid" : "5880ff305d15f416c89457b7" },
"car" : "mercedes",
"engine" : {
"sensor" : {
"temperatur" : "20",
"speed" : "100",
"hue" : "40"
}
},
"motor" : {
"Power" : "155",
"Topspeed" : "400"
}
}
{ "_id" : { "$oid" : "5880ff305d15f416c89457b7" },
"car" : "mercedes",
"engine" : {
"sensor" : {
"temperatur" : "50",
"speed" : "100",
"hue" : "40"
}
},
"motor" : {
"Power" : "155",
"Topspeed" : "400"
}
}
I would like to select the temperature for all Mercedes cars and receive it.
result should be like [20,50]
EDIT:
My code lookls like the following iam using JAVA:
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("test");
MongoCollection<Document> coll = database.getCollection("myTestCollection");
You can try something like this with regular query if you're okay with distinct values.
db.cars.distinct("engine.sensor.temperatur", {"car" : "mercedes"});
This will give you
[ "20", "50" ]
Update - Java equivalent:
List<String> temps = coll.distinct("engine.sensor.temperatur", new Document("car", "mercedes"), String.class).into(new ArrayList<>());
Update - Aggregation Option
Bson match = new Document("$match", new Document("car", "mercedes"));
Bson group = new Document("$group", new Document("_id", "$car").append("temps", new Document("$push", "$engine.sensor.temperatur")));
List<String> temps = (List<String>) coll.aggregate(Arrays.asList(match, group)).map(document -> document.get("temps")).first();

Fetching one element of array with sibling items (Without using aggregation or putting other sibling's value 1)

"translation" : [
{
"language" : "english",
"name" : "shahid Afridi",
"desc" : "batsmen",
"player" : "capten"
},
{
"language" : "spanish",
"name" : "shhid Ofridi",
"desc" : "batsmeen",
"player" : "capteen"
},
{
"language" : "french",
"name" : "hhid afrede is best",
"desc" : "batsmin",
"player" : "captn"
}
],
"auto-publish" : "publish",
"color" : "red",
"boolean" : "true"
I have this document in mongodb
In return
i want translation[0] with auto-publish, color and boolean.
Note: Without using aggregation or putting other sibling's value 1
You can use forEach on your cursor:
db.test.find({}).forEach(function(doc){
if (doc.hasOwnProperty('translation')){
var newdoc = {};
newdoc = doc.translation[0];
newdoc['auto-publish'] = doc['auto-publish'];
newdoc['color'] = doc['color'];
newdoc['boolean'] = doc['boolean'];
print(tojson(newdoc));
}
})
I don't think there's any other way to re-organize document as you need without using aggregation.

How to update particular array element in MongoDB

I am newbie in MongoDB. I have stored data inside mongoDB in below format
"_id" : ObjectId("51d5725c7be2c20819ac8a22"),
"chrom" : "chr22",
"pos" : 17060409,
"information" : [
{
"name" : "Category",
"value" : "3"
},
{
"name" : "INDEL",
"value" : "INDEL"
},
{
"name" : "DP",
"value" : "31"
},
{
"name" : "FORMAT",
"value" : "GT:PL:GQ"
},
{
"name" : "PV4",
"value" : "1,0.21,0.00096,1"
}
],
"sampleID" : "Job1373964150558382243283"
I want to update the value to 11 which has the name as Category.
I have tried below query:
db.VariantEntries.update({$and:[ { "pos" : 117199533} , { "sampleID" : "Job1373964150558382243283"},{"information.name":"Category"}]},{$set:{'information.value':'11'}})
but Mongo replies
can't append to array using string field name [value]
How one can form a query which will update the particular value?
You can use the $ positional operator to identify the first array element to match the query in the update like this:
db.VariantEntries.update({
"pos": 17060409,
"sampleID": "Job1373964150558382243283",
"information.name":"Category"
},{
$set:{'information.$.value':'11'}
})
In MongoDB you can't adress array values this way. So you should change your schema design to:
"information" : {
'category' : 3,
'INDEL' : INDEL
...
}
Then you can adress the single fields in your query:
db.VariantEntries.update(
{
{"pos" : 117199533} ,
{"sampleID" : "Job1373964150558382243283"},
{"information.category":3}
},
{
$set:{'information.category':'11'}
}
)