Spring - return nested documents using aggregation - mongodb

i have 2 class
class Team
{
#Id
var lateint id : String
var name : String? = null
var stadium : String? = null
var players : List<Players>? = null
}
class Player
{
#Id
var lateint id : String
var firstName : String? = null
var lastName : String? = null
var post : PlayerPost? = null
var number : Int? = null
}
i am trying to get a filtered list of player of a specific team, but i always get a wrong result.
this is my request
val teamCriteria = Criteria.where("_id").`is`(teamId)
val postCriteria = Criteria.where("post").`is`("DEFENDER")
val aggregation = Aggregation.newAggregation(
Aggregation.match(teamCriteria),
Aggregation.unwind("players"),
Aggregation.match(postCriteria),
)
return mongoDb.aggregate(aggregation, Team::class.java, Player::class.java).mappedResults
The problem is instead of getting a list of players as result, i get the team duplicated as the number of expected players..
expected result
[
{
"id" : "id1",
"firstName" : "player1"
"lastName" : "player1",
"number" : 2,
"post" : "DEFENDER"
},
{
"id" : "id2",
"firstName" : "player2"
"lastName" : "player2",
"number" : 3,
"post" : "DEFENDER"
}
]
i always get this result
[
{
"id" : "id1",
"name" : "team name"
"stadium" : "stadium name",
"players" : []
},
{
"id" : "id1",
"name" : "team name"
"stadium" : "stadium name",
"players" : []
}
]
Can sameone tell me what's wrong in my code?

Related

Get only nested Object from MongoDB by Spring Data mongoDb or mongo template

{
"_id" : "a9582f59-f52b-4fc8-84ab-cdd0bfb8dead",
"_class" : "com.db.Category",
"name" : "Cricket",
"subCategories" : [
{
"name" : "Gloves",
"creationDate" : NumberLong("1527404341099"),
"modificationDate" : NumberLong("1527404341099")
},
{
"name" : "Stumps",
"creationDate" : NumberLong("1527404369882"),
"modificationDate" : NumberLong("1527404369882")
},
{
"name" : "Bat",
"brandList" : [
{
"name" : "MRF",
"productDetails" : [
{
"name" : "Bat 111",
"price" : "1224",
"imageUrlList" : [
"https://s3.us-east-1.amazonaws.com/gasports/1527792222680-Bat_111",
"https://s3.us-east-1.amazonaws.com/gasports/1527792228375-Bat_111"
]
}
]
}
],
"creationDate" : NumberLong("1527424021629"),
"modificationDate" : NumberLong("1527424021629")
}
],
"creationDate" : NumberLong("1527404340938"),
"modificationDate" : NumberLong("1527404340938")
}
This is Category Document. Category has subcategory,Subcategory has brands and Brand has products.
#Document(collection="productInfo")
public class Category extends BaseProductInfo<Category> {
#Id
private String uid;
private String name;
private List<SubCategory> subCategories;
//Getters ans setters..
Now I have to get only for specific subcategory or Brand or Product. For this currently I am doing iteration to get object.
Is there any way in Spring Data Mongo Repository to get nested Object ?
You can write a method like this in your Category Repository class
Category findBySubCategories_BrandList_ProductDetails_Name(String name)
Just pass the product name you want to fetch. spring-data-mongodb will formulate the query based on your meethod name and fetch the documents matching the query.

Meteor Methods insert not working (mongodb)

I am trying to write a table with various numbers of rows and columns to a database. For this, I have a Criterion collection that saves the table headers and an Option collection that saves the table data.
The structure is like this:
for Criterion:
{
{ "_id" : "hId1", "name" : "Option Name", "tableId" : "tId1" },
{ "_id" : "hId2", "name" : "Rent", "score" : 9, "tableId" : "tId1" },
{ "_id" : "hId3", "name" : "Surface", "score" : 5, "tableId" : "tId1" },
{ "_id" : "hId4", "name" : "Price", "score" : 5, "tableId" : "tId1" },
{ "_id" : "hId5", "name" : "CPU", "score" : 5, "tableId" : "tId4" }
etc.
}
for Option:
{
{ "_id" : "id1", "score" : 5,
"hId1" : { "value" : "Apt 1" },
"hId2" : { "value" : "800 sqft", "score" : 1 },
"hId3" : { "value" : "$800", "score" : 3 },
etc.
"tableId" : "tId1"
}
{ "_id" : "id2", "score" : 5,
"hId1" : { "value" : "Apt 2" },
"hId2" : { "value" : "780 sqft", "score" : 10 },
"hId3" : { "value" : "$700", "score" : 3 },
etc.
"tableId" : "tId1"
}
etc.
}
The first row for Criterion will always have "Option Name". For the data above, the table with "tableId" = "tId1" would end up looking like this (tableId and headerId are the keys):
| Option Name | Surface | Price |
| =========== | ======== | ===== |
| Apt 1 | 800 sqft | $800 |
| Apt 2 | 780 sqft | $700 |
My code looks like this (imports/api/comparison.js):
/**
* Options are for the rows
*/
export var Option = new Mongo.Collection('option');
/**
* Criteria are the columns
*/
export var Criterion = new Mongo.Collection('criterion');
Meteor.methods({
'comparison.insertRow' (query, headerId, tableId, isFirst) {
check(query, Object);
check(headerId, String);
check(tableId, String);
check(isFirst, Boolean);
if(isFirst){
var data = {};
data._id = headerId;
data.tableId = tableId;
data.name = "Option Name";
Criterion.insert(data);
}
query._id = tableId;
Option.insert(query);
},
});
Where isFirst is a boolean expressing whether this is the first row in a table or not.
My query is constructed like this (imports/ui/Menu/DataInsert.jsx):
var query = {};
query.score = // value
// get the header separately
query[headerId] = {
value: //valueH from form
};
// Find the text field via the React ref
for (var i = 1, len = cols.length; i < len; i++) {
query[cols[i]._id] = {
value: //valueV from form,
score: //valueS from form
};
}
My files are available on the server because I am doing this in server/main.js: import '../imports/api/comparison.js';
The query gets inserted no problem into Option no problem.
Why isn't data getting inserted into Criterion (when isFirst = true)?
I did a console.log(data) and a console.log(query) and it looks like this:
whereas the data in the db looks like this:
#jordanwillis was correct above, this was happening because I was setting the _id manually on the query. I did need to set the id, but I needed to set the tableId.
So, for the record, this is what I did:
'comparison.insertRow' (query, headerId, tableId, isFirst) {
check(query, Object);
check(headerId, String);
check(tableId, String);
check(isFirst, Boolean);
if(isFirst){
var data = {};
data._id = headerId;
data.tableId = tableId;
data.name = "Option Name";
Criterion.insert(data);
}
query.tableId = tableId;
Option.insert(query);
},
And my foreign keys are tableId and headerId (which is part of query).

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

Converting Firebase data into Swift array

This is how my Firebase data looks like:
[ {
"adress" : "Högåsstigen 10 332 33 Gislaved",
"helg" : "18:00-02:00",
"latitude" : 57.2985,
"longitude" : 13.54326,
"namn" : "Restaurang Åsen",
"outlet" : 0,
"phone" : "0371-123456",
"star" : 0,
"tag" : "Restaurang",
"vardag" : "10:00-19:30"
}, {
"adress" : "Högåsstigen 12 332 33 Gislaved",
"helg" : "18:00-02:00",
"latitude" : 57.9985,
"longitude" : 13.94326,
"namn" : "Kalles ställe",
"outlet" : 0,
"phone" : "0371-123456",
"star" : 2,
"tag" : "Restaurang",
"vardag" : "10:00-19:30"
}, {
"adress" : "Högåsstigen 15 332 33 Gislaved",
"helg" : "18:00-02:00",
"latitude" : 55.603384,
"longitude" : 13.020619,
"namn" : "Olles Pub",
"outlet" : 0,
"phone" : "0371-123456",
"star" : 1,
"tag" : "Krog",
"vardag" : "10:00-19:30"
} ]
I want to grab "adress" from the database.
I'm having problem to convert the data I grab from Firebase to append into an array so I can use them later. I get the error "Value of type 'String' has no member 'generator'".
I have no idea how to proceed in my coding, any suggestions?
var adresserArray = [String]()
let ref = Firebase(url: "https://HIDINGMYURL.firebaseio.com/")
ref.observeEventType(.ChildAdded, withBlock: {snapshot in
let adresser = (snapshot.value.objectForKey("adress")) as! String!
for add in adresser{
adresserArray.append(adresser)
}
})
You are trying to iterate over String here
let adresser = (snapshot.value.objectForKey("adress")) as! String!
for add in adresser{
adresserArray.append(adresser)
}
try just replace this code with
let adresser = (snapshot.value.objectForKey("adress")) as! String
adresserArray.append(adresser)

Spring data mongodb check inside array whether value presents

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