这是我的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"
}
}
我想将其作为键值对获取: 键应为“properties.device_id”并值整个记录。
像这样
[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"
}
}
有没有办法在不迭代记录的情况下获得这样的结果?
$addFields
管道阶段创建一个新字段,例如 root
,它是包含两个字段 k
和 v
的文档数组,其中:
The k field contains the field name.
The v field contains the value of the field.
在您的情况下,
k
应该是device_id
字段。由于这是双精度类型,因此您需要将其转换为字符串以供稍后使用。所以你的初始管道如下所示:
db.collection.aggregate([
{
"$addFields": {
"root": [
{
"k": { "$substr": [ "$properties.device_id", 0, -1 ] },
"v": "$$ROOT"
}
]
}
}
])
将返回以下文件
/* 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"
}
}
}
]
}
$arrayToObject
运算符,以便将新添加的根转换为以 device_id
作为键的对象:
db.collection.aggregate([
{
"$addFields": {
"root": [
{
"k": { "$substr": [ "$properties.device_id", 0, -1 ] },
"v": "$$ROOT"
}
]
}
},
{
"$addFields": {
"root": {
"$arrayToObject": "$root"
}
}
}
])
输出:
/* 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"
}
}
}
}
$replaceRoot
管道运算符来获取所需的输出:
db.collection.aggregate([
{
"$addFields": {
"root": [
{
"k": { "$substr": [ "$properties.device_id", 0, -1 ] },
"v": "$$ROOT"
}
]
}
},
{
"$addFields": {
"root": {
"$arrayToObject": "$root"
}
}
},
{ "$replaceRoot" : { "newRoot": "$root" } }
])
输出
/* 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"
}
}
}
@chridam 的答案并不返回实际的键值 hashMap,而是返回一个对象数组,其值位于单个键后面。
[ {"23613":{...} }, {"23658":{...} }]
vs.
{"23613":{...}, "23658":{...} }
要获取实际的键值对 HashMap 结果,您可以使用以下聚合:
db.collection.aggregate([
{
$group: {
_id: "",
data: {
$mergeObjects: {
$arrayToObject: [
[
{
k: {
$toString: "$properties.device_id"
},
v: "$$ROOT"
}
]
]
}
}
}
},
{
$replaceRoot: {
newRoot: "$data"
}
}
]);
这将返回:
[
{
"23613": {
"_class": "com.vuelogix.location.model.LocationModel",
"_id": "5a65a047992e3c2572f74102",
"geometry": {
"_class": "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates": [
77.065659,
19.145168
],
"type": "Point"
},
"properties": {
"address": "Purna to Loha Rd, Maharashtra 431511, India",
"device_id": 23613,
"last_updated": "2018-01-22T08:26:47.237Z"
},
"type": "Feature"
},
"23658": {
"_class": "com.vuelogix.location.model.LocationModel",
"_id": "5a65ae1e992e3c2572f74114",
"geometry": {
"_class": "com.vuelogix.location.model.geojson.geometry.Point",
"coordinates": [
74.956284,
28.497661
],
"type": "Point"
},
"properties": {
"address": "Taranagar - Churu Rd, Chalkoi Baneerotan, Rajasthan 331001, India",
"device_id": 23658,
"last_updated": "2018-01-22T09:25:50.893Z"
},
"type": "Feature"
}
}
]
如您所见,结果仍然是一个数组,因为聚合函数的行为始终是返回一个数组。从积极的一面来看,这个数组将始终只包含 1 个文档/对象。这个对象就是你的键值对HashMap。因此,每当您在应用程序中使用结果时,您始终必须从结果数组中获取第一个文档:
result.get(0)
或result[0]
或任何适合您的编程语言的内容。
聚合查询说明:
$group
:
_id: ""
可确保所有文档都添加/合并到一个组中。$mergeObjects
$arrayToObject
$replaceRoot
:
device_id
值作为键。