{
"_id" : ObjectId("593947f95ccc81692670e6b4"),
"user1" : 100,
"user2" : 4,
"messages" : [
{
"sender" : 100,
"datetime" : ISODate("2017-06-08T12:50:01Z"),
"body" : "hiii 0"
},
{
"sender" : 100,
"datetime" : ISODate("2017-06-09T12:50:01Z"),
"body" : "hiii 1"
},
{
"sender" : 4,
"datetime" : ISODate("2017-06-10T12:50:01Z"),
"body" : "hiii 2"
}
]
}
我希望找到user1或user2之一为4的所有邮件,并仅列出发件人!= 4的邮件。
寻找输出:
"user1" : 100,
"user2" : 4,
"messages" : [
{
"sender" : 100,
"datetime" : ISODate("2017-06-08T12:50:01Z"),
"body" : "hiii 0"
},
{
"sender" : 100,
"datetime" : ISODate("2017-06-09T12:50:01Z"),
"body" : "hiii 1"
}
试过这个
db.chat.find({ $and:[
{ $or : [ {"user1":4},{"user2":4} ] },
{"messages.sender": {$ne :4}}
]}).pretty()
但没有工作。
答案 0 :(得分:1)
您可以使用.aggregate
和$filter
db.chat.aggregate([
{
"$match": {
"$or": [{"user1": 4}, {"user2": 4}]
}
},
{"$project": {
"user1" : 1,
"user2" : 1,
"messages": {"$filter": {
input: "$messages",
as: 'message',
cond: {$ne: ['$$message.sender', 4]}
}
}
}}
])
要仅返回消息计数,您可以使用此
db.chat.aggregate([
{
"$match": {
"$or": [{"user1": 4}, {"user2": 4}]
}
},
{"$project": {
"user1" : 1,
"user2" : 1,
"messageCount": {
$size: {
"$filter": {
input: "$messages",
as: 'message',
cond: {$ne: ['$$message.sender', 4]}
}
}
}
}}
])
或者,如果您想要返回所有messages
和消息计数,则可以使用此查询
db.chat.aggregate([
{
"$match": {
"$or": [{"user1": 4}, {"user2": 4}]
}
},
{
"$project": {
"user1": 1,
"user2": 1,
"messages": {
"$filter": {
input: "$messages",
as: 'message',
cond: {$ne: ['$$message.sender', 4]}
}
}
}
},
{
"$project": {
user1: 1,
user2: 1,
messages: 1,
messagesCount: { $size: "$messages" }
}
}
])
答案 1 :(得分:0)
db.demo.aggregate(
// Pipeline
[
// Stage 1
{
$match: {
$or:[{user1:4},{user2:4}]
}
},
// Stage 2
{
$unwind: "$messages"
},
// Stage 3
{
$match: {
'messages.sender':{$ne:4}
}
},
// Stage 4
{
$group: {
_id:{_id:'$_id',user1:'$user1',user2:'$user2'},
messages:{$addToSet:'$messages'}
}
},
]
);
上面提到的聚合查询在管道
中执行下面提到的聚合阶段$ match运算符匹配user1或者value的文档 user2等于4.
$ unwind运算符将messages数组拆分为单独的文档 messages数组中包含的每个值。
$ match运算符过滤发件人对象不相等的邮件 到4。
$ group operator根据_id字段和值的值对文档进行分组 将消息推送到数组