我最近开始使用MongoDB保存项目中的数据,基本想法如下。
在服务器端,我在WebSocket上接收一些JSON对象,并将其存储在数据库中。
我收到的数据看起来像这样:
{
{ident: "message_1"},
data:
[
{id: "data_1", value : 10},
{id: "data_2", value : 20},
{id: "data_3", value : 40},
{id: "data_4", value : 60},
{id: "data_4", value : 60},
],
timestamp : 12234456
}
我目前正在数据库中保存整个JSON对象。
服务器还应该处理用户http请求,在那里它向数据库查询请求的数据。用户请求总是针对data
数组的一个元素和时间戳。因此,服务器的响应应该是这样的:
{ id: "data_1", value : 10, timestamp : 12234456}
我尝试将db.collection.find与$elemMatch一起使用,但我的输出仍然包含data
数组和所需的元素。
{
data:
[{
id: "data_1",
value: 10
}],
timestamp : 12234456
}
因此,我的问题是,是否有可能查询数据库并只返回"数据"数组中所需的元素和时间戳,或者我需要在读取数据库后重新创建响应JSON对象。
致以亲切的问候。
欢迎来到mongo世界。您可以通过聚合轻松实现这一点
$uwnind
来解构数组$match
获取期望值$addFields
向对象添加新字段$replaceRoot
使对象成为根
这是代码
db.collection.aggregate([
{ "$unwind": "$data" },
{ "$match": { "data.id": "data_1" } },
{ "$addFields": { "data.timestamp": "$timestamp" } },
{ "$replaceRoot": { "newRoot": "$data" } }
])
正在工作的Mongo游乐场
尽管@varman的答案对这个问题是正确的,但为了更好地匹配我的情况,即数组data
将有很多元素(超过100个(,因为注释"展开"中的@varman可能会很昂贵,特别是当数组包含大量元素时。因此,在理想的情况下,当数组只包含不需要的元素时,我更喜欢进行"展开",以实现这一点,我将顺序更改为:
- 使用
"$match
仅获取具有所需data
元素的文档
{ "$match": { "data.id": "data_1" } }
- 使用
$project
和$filter
从数据中筛选出不需要的元素
$project: {
data: {
$filter: {
input: "$data",
as: "data",
cond: {$eq: ["$$data.id", "data_1"]}
}
},
"timestamp": 1,
"_id": 0
}
- 现在添加
timestamp
字段作为正确答案
{ $addFields: {"data.timestamp": "$timestamp"} }
- 使用
unwind
从输入文档中解构data
数组字段,为每个元素输出一个文档
{
$unwind: "$data"
}
- 然后使用
$replaceRoot
将输入文档替换为data
字段
{"$replaceRoot": {"newRoot": "$data"}}
希望这对任何需要这样做的人都有用,如果你对我目前的设置有任何建议/改进,请我征求意见,因为我是MongoDB的新手。
运行示例Mongo Playground