Here are the records in my mongodb
{
"_id": "5a65a047992e3c2572f74102",
"_class": "com.vuelogix.location.model.LocationModel",
"type": "Feature",
"properties": {
"address": "Purna to Loha Rd, Maharashtra 431511, India",
"device_id": 23613,
"last_updated": "2018-01-22T08:26:47.237Z"
},
"geometry": {
"_class": "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates": [77.065659, 19.145168],
"type": "Point"
}
},
{
"_id": "5a65ae1e992e3c2572f74114",
"_class": "com.vuelogix.location.model.LocationModel",
"type": "Feature",
"properties": {
"address": "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id": 23658,
"last_updated": "2018-01-22T09:25:50.893Z"
},
"geometry": {
"_class": "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates": [74.956284, 28.497661],
"type": "Point"
}
}
I want to get it as a key value pair: key should be "properties.device_id" and value entire record.
Like this
[23613] => {
"_id": "5a65a047992e3c2572f74102",
"_class": "com.vuelogix.location.model.LocationModel",
"type": "Feature",
"properties": {
"address": "Purna to Loha Rd, Maharashtra 431511, India",
"device_id": 23613,
"last_updated": "2018-01-22T08:26:47.237Z"
},
"geometry": {
"_class": "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates": [77.065659, 19.145168],
"type": "Point"
}
}
[23658] => {
"_id": "5a65ae1e992e3c2572f74114",
"_class": "com.vuelogix.location.model.LocationModel",
"type": "Feature",
"properties": {
"address": "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id": 23658,
"last_updated": "2018-01-22T09:25:50.893Z"
},
"geometry": {
"_class": "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates": [74.956284, 28.497661],
"type": "Point"
}
}
Is there any way to get a result like this without iterating through records?
Use the $addFields
pipeline stage to create a new field say root
that is an array of a document that contains two fields, k
and v
where:
The k field contains the field name.
The v field contains the value of the field.
In your case k
should be the device_id
field. Since this is a double type, you need a hack to convert it to a string for later. So your initial pipeline looks as follows:
db.collection.aggregate([
{
"$addFields": {
"root": [
{
"k": { "$substr": [ "$properties.device_id", 0, -1 ] },
"v": "$$ROOT"
}
]
}
}
])
which will return the following documents
/* 1 */
{
"_id" : "5a65a047992e3c2572f74102",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Purna to Loha Rd, Maharashtra 431511, India",
"device_id" : 23613.0,
"last_updated" : "2018-01-22T08:26:47.237Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
77.065659,
19.145168
],
"type" : "Point"
},
"root" : [
{
"k" : "23613",
"v" : {
"_id" : "5a65a047992e3c2572f74102",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Purna to Loha Rd, Maharashtra 431511, India",
"device_id" : 23613.0,
"last_updated" : "2018-01-22T08:26:47.237Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
77.065659,
19.145168
],
"type" : "Point"
}
}
}
]
}
/* 2 */
{
"_id" : "5a65ae1e992e3c2572f74114",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id" : 23658.0,
"last_updated" : "2018-01-22T09:25:50.893Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
74.956284,
28.497661
],
"type" : "Point"
},
"root" : [
{
"k" : "23658",
"v" : {
"_id" : "5a65ae1e992e3c2572f74114",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id" : 23658.0,
"last_updated" : "2018-01-22T09:25:50.893Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
74.956284,
28.497661
],
"type" : "Point"
}
}
}
]
}
From here you would want to leverage the $arrayToObject
operator so that you convert the newly added root to an object with device_id
as the key:
db.collection.aggregate([
{
"$addFields": {
"root": [
{
"k": { "$substr": [ "$properties.device_id", 0, -1 ] },
"v": "$$ROOT"
}
]
}
},
{
"$addFields": {
"root": {
"$arrayToObject": "$root"
}
}
}
])
which outputs:
/* 1 */
{
"_id" : "5a65a047992e3c2572f74102",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Purna to Loha Rd, Maharashtra 431511, India",
"device_id" : 23613.0,
"last_updated" : "2018-01-22T08:26:47.237Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
77.065659,
19.145168
],
"type" : "Point"
},
"root" : {
"23613" : {
"_id" : "5a65a047992e3c2572f74102",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Purna to Loha Rd, Maharashtra 431511, India",
"device_id" : 23613.0,
"last_updated" : "2018-01-22T08:26:47.237Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
77.065659,
19.145168
],
"type" : "Point"
}
}
}
}
/* 2 */
{
"_id" : "5a65ae1e992e3c2572f74114",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id" : 23658.0,
"last_updated" : "2018-01-22T09:25:50.893Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
74.956284,
28.497661
],
"type" : "Point"
},
"root" : {
"23658" : {
"_id" : "5a65ae1e992e3c2572f74114",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id" : 23658.0,
"last_updated" : "2018-01-22T09:25:50.893Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
74.956284,
28.497661
],
"type" : "Point"
}
}
}
}
The last step in the pipeline would be to use $replaceRoot
pipeline operator to get your desired output:
db.collection.aggregate([
{
"$addFields": {
"root": [
{
"k": { "$substr": [ "$properties.device_id", 0, -1 ] },
"v": "$$ROOT"
}
]
}
},
{
"$addFields": {
"root": {
"$arrayToObject": "$root"
}
}
},
{ "$replaceRoot" : { "newRoot": "$root" } }
])
Output
/* 1 */
{
"23613" : {
"_id" : "5a65a047992e3c2572f74102",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Purna to Loha Rd, Maharashtra 431511, India",
"device_id" : 23613.0,
"last_updated" : "2018-01-22T08:26:47.237Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
77.065659,
19.145168
],
"type" : "Point"
}
}
}
/* 2 */
{
"23658" : {
"_id" : "5a65ae1e992e3c2572f74114",
"_class" : "com.vuelogix.location.model.LocationModel",
"type" : "Feature",
"properties" : {
"address" : "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id" : 23658.0,
"last_updated" : "2018-01-22T09:25:50.893Z"
},
"geometry" : {
"_class" : "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates" : [
74.956284,
28.497661
],
"type" : "Point"
}
}
}