How to get the nested object in projection in mongodb find query.
[
{
"apikey": 1,
"meta": {
"region": {
"country": "India",
"city": "bangalore",
"pincode": 560067
},
"address": {
"houseNo": "G/C 42 Whitefield boulavourd",
"landmark": "whitefield boulavourd"
}
}
},
{
"apikey": 2,
"meta": {
"region": {
"country": "Germaany",
"city": "Munich",
"pincode": 80297
},
"address": {
"houseNo": "Zweibrückenstraße 12",
"landmark": "Zweibrückenstraße 12"
}
}
}
]
I was trying to fetch the region of apikey 2. I tried below find query
I tried find query i.e.
db.collection.find({
"apikey": "2"
},
{
"projection": {
"_id": 0,
"apikey": 1,
"meta.region": 1
}
})
I am getting error, regarding that can not do inclusion on field meta.region in exclusion projection.
Is there any other way to achieve this problem.
I want the output,
[
{
"apikey":2,
"region": {
"country": "Germaany",
"city": "Munich",
"pincode": 80297
}
}
]
This is the mongoplayground
Remove projection (wrapping) level.
db.collection.find({
apikey: 2
},
{
"_id": 1,
"apikey": "$apikey",
"region": "$meta.region"
})
Sample Mongo Playground
Related
I have a document as below in my sample collection
{
_id: 1,
"name": "NA",
request_address: [
{
"state": "kyz",
"city": "abc",
"housenbr": [
"123",
"345",
"456"
]
},
{
"state": "pqr",
"city": "def",
"housenbr": [
"898",
"765"
]
},
{
"state": "wrt",
"city": "zdc"
}
]
}
when I use
db.sample.find({_id:1},{request_address:{$elemMatch:{state:"pqr"}}})
I am having only the below data which is as expected
{
_id: 1,
request_address: [
{
"state": "pqr",
"city": "def",
"housenbr": [
"898",
"765"
]
}
]
}
but when I use this in the spring version
Query query = new Query;
query.addCriteria(Criteria.where("_id").is(1));
query.addCriteria(Criteria.where("request_address").elemMatch(Criteria.where("state").is("PR)));
mongoConfiguration.mongoTemplate().findOne(query, sampleEntity.class)
I am having an error No property request found for type sampleEntity.class.
what is the wrong I am doing can you provide the details
{
"id": "1505036191456227329",
"materialList": [
{
"id": "1505035441229459457",
"model": "",
"parentId": "0",
},
{
"id": "1505035441229459458",
"model": "",
"parentId": "1505035441229459457",
}, {
"id": "1505035441229459459",
"model": "",
"parentId": "1505035441229459457",
},{
"id": "1505035441229459460",
"model": "",
"parentId": "1505035441229459459",
}
]
}
this is my data,I want to find all sub data IDS with ID 1505035441229459457 under the materiallist。
The result of the query is 1505035441229459458,1505035441229459459,1505035441229459460
You will have to use $elemMatch for this.
Ex -> db.collection.find( { materialList: { $elemMatch: {id:
1505035441229459457 } } })
Below is the sample data:
db.infos.find()
{
"groupId": "1111",
"customerId": "A100",
"tracks": [{
"trackId": "234",
"infos": [{
"location": {
"address": "street1",
"city": "test",
"country": "US"
}
},
{
"location": {
"address": "street2",
"city": "test",
"country": "US"
}
},
{
"location": {
"address": "street3",
"city": "test",
"country": "US"
}
}
]
}]
}
{
"groupId": "2222",
"customerId": "A100",
"tracks": [{
"trackId": "345",
"infos": [{
"location": {
"address": "street4",
"city": "test",
"country": "US"
}
},
{
"location": {
"address": "street5",
"city": "test",
"country": "US"
}
},
{
"location": {
"address": "street5",
"city": "test",
"country": "US"
}
}
]
}]
}
{
"groupId": "2222",
"customerId": "A100",
"tracks": [{
"trackId": "666",
"infos": [{
"location": {
"address": "street4",
"city": "test",
"country": "US"
}
},
{
"location": {
"address": "street5",
"city": "test",
"country": "US"
}
},
{
"location": {
"address": "street5",
"city": "test",
"country": "US"
}
}
]
}]
}
We need a query to get the length of "infos" sub array at groupId level. In the above sample data, we need the below output:
1111, 3
2222, 6
Tried below, but its not working:
db.infos.aggregate([{"$project": {"groupId": "$groupId", "samples": "$tracks.infos"}}, {"$group": {"_id": "$groupId", "samples": {"$push": "$samples"}}}, {"$project": {"_id": 1, "samples": {"$size": "$samples"}}}], { "allowDiskUse": true });
Also with large amount of data, above query is throwing an ExceededMemoryLimit exception:
2021-07-10T07:20:14.415+0000 E QUERY [js] Error: command failed: {
"ok" : 0,
"errmsg" : "$push used too much memory and cannot spill to disk. Memory limit: 104857600 bytes",
"code" : 146,
"codeName" : "ExceededMemoryLimit"
} : aggregate failed :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
doassert#src/mongo/shell/assert.js:18:14
_assertCommandWorked#src/mongo/shell/assert.js:580:17
assert.commandWorked#src/mongo/shell/assert.js:673:16
DB.prototype._runAggregate#src/mongo/shell/db.js:260:9
DBCollection.prototype.aggregate#src/mongo/shell/collection.js:1074:12
#(shell):1:1
This should work with unwind:
db.collection.aggregate([
{
$unwind: "$tracks"
},
{
$group: {
"_id": "$groupId",
"count": {
"$sum": {
"$size": "$tracks.infos"
}
}
}
}
])
Even if your tracks array has more than one object this will add them up. Playground
I have the following mongodb documents:
{
"_id": "",
"name": "example1",
"colors": [
{
"id": 1000000,
"properties": [
{
"id": "1000",
"name": "",
"value": "green"
},
{
"id": "2000",
"name": "",
"value": "circle"
}
]
} ]
}
{
"_id": "",
"name": "example2",
"colors": [
{
"id": 1000000,
"properties": [
{
"id": "1000",
"name": "",
"value": "red"
},
{
"id": "4000",
"name": "",
"value": "box"
}
]
} ]
}
I would like to get distinct queries on the value field in the array where id=1000
db.getCollection('product').distinct('colors.properties.value', {'colors.properties.id':{'$eq': 1000}})
but it returns all values in the array.
The expected Result would be:
["green", "red"]
There are a lot of way to do.
$match eliminates unwanted data
$unwind de-structure the array
$addToSet in $group gives the distinct data
The mongo script :
db.collection.aggregate([
{
$match: {
"colors.properties.id": "1000"
}
},
{
"$unwind": "$colors"
},
{
"$unwind": "$colors.properties"
},
{
$match: {
"colors.properties.id": "1000"
}
},
{
$group: {
_id: null,
distinctData: {
$addToSet: "$colors.properties.value"
}
}
}
])
Working Mongo playground
I have Json which have values like state_city details this contains information like which city belongs to which state -
Need to query it for particular state name which will gives me all cities that belongs to that state.
db.collection.find({
"count": 10,
"state.name": "MP"
})
[
{
"collection": "collection1",
"count": 10,
"state": [
{
"name": "MH",
"city": "Mumbai"
},
{
"name": "MH",
"city": "Pune"
},
{
"name": "UP",
"city": "Kanpur"
},
{
"name": "CG",
"city": "Raipur"
}
]
},
{
"collection": "collection2",
"count": 20,
"state": [
{
"name": "MP",
"city": "Indore"
},
{
"name": "MH",
"city": "Bhopal"
},
{
"name": "UP",
"city": "Kanpur"
},
{
"name": "CG",
"city": "Raipur"
}
]
}
]
You have to use aggregate query to get only matching elements in array :
db.collection.aggregate([{
$unwind: "$content.state"
},
{
$match: {
"content.state.name": "MH",
"count": 10
}
},
{
$group: {
_id: "$content.state.city",
}
},
{
$addFields: {
key: 1
}
},
{
$group: {
_id: "$key",
cities: {
$push: "$_id"
}
}
},
{
$project: {
_id: 0,
cities: 1
}
}
])
This query will return :
{
"cities": [
"Pune",
"Mumbai"
]
}
The following query would be the solution.
db.collection.find({ "count": 10, "state":{"name": "MP"}})
For more complex queries, $elemMatch is also available.