reactjs - 关于高级聊天的MongoDB聚合帮助
问题描述
我告诉你我需要 MongoDB 中的查询帮助,我需要从聊天中获取数据,
我有一个集合:用户房间消息
碰巧在这个聚合中,我带来了每个聊天的最后一条消息(在聊天界面中继续对话)
此外,我还带来了有关他们各自聊天用户的信息,它们按日期“ASC”排序
发生的情况是,在房间集合中有一个名为“deleted_by”的属性,这是一种安排,每次该对话的用户删除对话时都会进行“推送”,并且具有:_id(用户 id)deleted_date(日期对话被删除)
我需要的是让聚合是否给我带来最后一条消息,具体取决于:如果用户删除了对话,以及它的日期“createdAt”大于删除对话日期“deleted_date”的最后一条消息是什么" 理想情况下,如果在删除日期之后没有消息,您应该无法进行聊天
需要强调的是,每次用户再次删除对话时,都会为用户更新此删除日期
如果这不是正确的方法,我希望有人指导我应该如何处理消除对话的问题(但它只对执行它的用户消除,而不是为另一个)和分开从开始对话开始,其他用户继续拥有所有消息,但删除它的用户仅拥有自重新开始以来的对话
data_chats = rooms_db.aggregate([
{
'$match': {
'usuarios': ObjectId(usuario['_id']),
}
},
{
'$lookup': {
'from': 'mensajes',
'localField':'mensajes',
'foreignField': '_id',
'as': 'mensaje'
}
},
{
'$lookup': {
'from': 'usuarios',
'localField':'usuarios',
'foreignField': '_id',
'as': 'usuario'
}
},
{"$unwind":"$usuario"},
{"$unwind": "$usuario._id"},
{"$match": {"usuario._id": {"$nin": [ObjectId(usuario['_id'])]}}},
{
'$project': {
'mensaje': {
'$cond': [
{'$eq': [ "$deleted_by._id", ObjectId(usuario['_id'])]},
#{'$slice': ['$mensaje', -1]},
{'$filter': {
'input': "$deleted_by",
'as': "deleted_convers",
'cond': { '$gte': [ "$$deleted_convers.delete_date", '$mensaje.createdAt'] }
}
},
{'$filter': {
'input': "$deleted_by",
'as': "deleted_convers",
'cond': { '$gte': [ "$$deleted_convers.delete_date", '$mensaje.createdAt'] }
}
},
]
},#{'$slice': ['$mensaje', -1]},
'usuarios': {
'id': '$usuario._id',
'nombre_usuario': '$usuario.nombre_usuario',
'foto_url': '$usuario.foto_url'
},
'deleted_by': {
'$filter': {
'input': "$deleted_by",
'as': "deleted_convers",
'cond': { '$eq': [ "$$deleted_convers._id", ObjectId(usuario['_id'])] }
}
}
}
},
{
'$sort': {'mensaje.createdAt': -1}
},
])
消息文档:[在此处输入图片描述][1] [1]:https://i.stack.imgur.com/BiMLe.png
房间文档:[在此处输入图片描述][2] [2]:https://i.stack.imgur.com/LHvNi.png
我需要得到这个:
{
"_id":"ObjectId(""5fff8086d1f75d0313fd20d5"")",
"usuarios":[
{
"id":"ObjectId(""5fff7521d1f75d0313fd20d4"")",
"nombre_usuario":"dagoberticohd",
"foto_url":"http://etc..."
},
{
"id":"ObjectId(""5fff7521d1f75d0313fd20d4"")",
"nombre_usuario":"dagoberticohd",
"foto_url":"http://etc..com"
}
],
"mensaje":[
],
"deleted_by":[
{
"_id":"ObjectId(""5ffb8107e3d065e99e0949bd"")",
"delete_date":"2021-01-25T23:21:42.580627"
}
]
}
我明白了:
{
"_id":"ObjectId(""5fff8086d1f75d0313fd20d5"")",
"usuarios":[
{
"id":"ObjectId(""5fff7521d1f75d0313fd20d4"")",
"nombre_usuario":"dagoberticohd",
"foto_url":"http://etc..."
},
{
"id":"ObjectId(""5fff7521d1f75d0313fd20d4"")",
"nombre_usuario":"dagoberticohd",
"foto_url":"http://etc..com"
}
],
"mensaje":[
{
"_id":"ObjectId(""600cd16b3de98712caa8b7dc"")",
"text":"Xx",
"createdAt":"2021-01-24T01:46:19.377185",
"autor":"ObjectId(""5ffb8107e3d065e99e0949bd"")",
"room":"ObjectId(""5fff8086d1f75d0313fd20d5"")",
"received":false
}
],
"deleted_by":[
{
"_id":"ObjectId(""5ffb8107e3d065e99e0949bd"")",
"delete_date":"2021-01-25T23:21:42.580627"
}
]
}
解决方案
阶段:
- 获取使用存在的文档。(在本例中,_id === 2 的用户)
- “加入”消息文档。
- “加入”用户文档。
- 传播消息。
- 按messages.createdAt 排序。
- 将这个阶段的结果限制为 1,因为我只需要最后一个。
- 如果用户这样做了,请添加 delete_by。
- 如果 "$delete_by.delte_date" > "$messages.createdAt" 返回 null 否则返回消息列表。
db.room.aggregate([
{
$match: {
usuarios: 2
}
},
{
"$lookup": {
"from": "message",
"localField": "messages",
"foreignField": "_id",
"as": "messages"
}
},
{
"$lookup": {
"from": "user",
"localField": "usuarios",
"foreignField": "_id",
"as": "usuarios"
}
},
{
"$unwind": "$messages"
},
{
"$sort": {
"messages.createdAt": -1
}
},
{
"$limit": 1
},
{
"$addFields": {
"delete_by": {
"$filter": {
"input": "$delete_by",
"as": "delete_by",
"cond": {
"$eq": [
"$$delete_by._id",
2
]
}
}
}
}
},
{
"$addFields": {
"messages": {
"$cond": {
if: {
"$gte": [
"$delete_by.delte_date",
"$messages.createdAt"
]
},
then: null,
else: "$messages"
}
}
}
}
])
推荐阅读
- java - Autowire 静态接口对象 - Spring Boot 2.0
- python - tkinter 窗口在被破坏后不会消失
- c# - 如何将文件列的值传递给 ILNumerics 3D 图形?
- python-3.x - 如何在pyspark中使用其他Rdd元素的所有可能组合创建新Rdd?
- python - 如何从Python的excel中的不同位置写入多个单元格
- java - 如何动态声明实例变量?
- c# - 通过 ASP.NET CORE WEB API 并发请求和共享 HttpClient
- mysql - 选择 MySQL 中的所有记录,除非记录存在于另一个表中
- mongodb - 如何在 mongodb 中使用 $gte 和 $lte 作为日期?
- java - 从 String Spark Java 创建数据集(无 RDD)