如何仅从Mongodb聚合返回某些字段($ project),同时还使用$ match,$ lookup和$ filter [英] How do I only return SOME fields ($project) from Mongodb aggregation, while also using $match, $lookup AND $filter

查看:1080
本文介绍了如何仅从Mongodb聚合返回某些字段($ project),同时还使用$ match,$ lookup和$ filter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我非常想从此查询中获取想要的内容...但是我只希望返回某些字段,而现在它正在返回所有这些字段



注意:这是一种改进:我现在要问的是如何只返回 某些字段 ,而我的类似内容是问题询问如何在开始日期和结束日期之间返回数据



此外,有人可以提供答案吗?在我的数据集中使用 MongoDB Playground ,这样我就可以尝试一下...我不太清楚如何为数据集命名,以便它们在操场上工作!



注册架构



  const猫鼬= require('猫鼬'); 
const Schema = mongoose.Schema;
const RegisterSchema = new Schema({
userId:{type:Schema.Types.ObjectId,required:true},
accessToken:{type:String,required:true,默认值:null} ,
})
module.exports = Register = mongoose.model('register',RegisterSchema)

这里有一些寄存器数据

  [
{
_id: 5eac9e815fc57b07f5d0d29f,
userId: 5ea108babb65b800172b11be,
accessToken: 111
},
{
_id : 5ecaeba3c7b910d3276df839,
userId: 5e6c2dddad72870c84f8476b,
accessToken: 222
}
]

下一个文档包含通过accessToken与寄存器架构相关的数据



Notifications



  const mongoose = require('mongoose'); 
const Schema = mongoose.Schema;
const NotificationSchema = new Schema({
accessToken:{type:String,required:true},
summaryId:{type:Number,required:true},
dateCreated:{类型:日期,默认值:Date.now},

//我不希望它们在最终结果中返回
dontWantThis1:{type:Number,必填:true},
dontWantThis2:{type:Number,必填:true},
})
module.exports = Notification = mongoose.model('notification',NotificationSchema)

以下是一些通知数据

  [{
_id: 5ebf0390c719e60004f42e74,
accessToken: 111,
summaryId:1111,
dontWantThis1:61 ,
dontWantThis2:62,
dateCreated: 2020-04-17T00:00:00.000 + 00:00},
{
_id: 6ebf0390c719e60004f42e76,
accessToken: 222,
summaryId:2221,
dontWantThis1:71,
dontWantThis2: 72,
dateCreated: 2020-04-18T00:00:00.000 + 00:00},
{
_id: 6ebf0390c719e60004f42e78,
accessToken : 111,
summaryId:1112,
dontWantThis1:611,
dontWantThis2:622,
dateCreated: 2020-05-25T00 :00:00.000 + 00:00},
{
_id: 6ebf0390c719e60004f42e80,
accessToken: 222,
summaryId:2222,
dontWantThis1:711,
dontWantThis2:722,
dateCreated: 2020-05-26T00:00:00.000 + 00:00}
]



Works,返回两个日期之间的数据,但是



此代码返回所有内容,包括'dontWantThis1'和'dontWantThis2'



注意



我不希望以'dontWantThis'开头的字段-但这只是为了显示我不想要的字段...我从字面上不想排除以'dontWantThis'开头的字段...。他们可以命名为 foo, apple或 dog它们只是以这种方式命名,以表示我不希望它们

  
//确保输入日期是真正的日期对象
//我只想查看五月的通知(在此示例中)
var dateStart = new Date ('2020-05-01T00:00:00.000 + 00:00');
var dateEnd = new Date(’2020-05-30T00:00:00.000 + 00:00’);

var match = {$ match:{userId:mongoose.Types.ObjectId(userId)}};

var查找= {
$ lookup:
{
来自: my_Notifications,
localField: accessToken,
foreignField: accessToken,
为:通知
}
};

var dateCondition = {$ and:[
{$ gte:[ $$ item.dateCreated,dateStart]},
{$ lte:[ $$ item .dateCreated,dateEnd]}
]}

var project = {
$ project:{
通知:{
$ filter:{
输入: $ notifications,
as: item,
cond:dateCondition
}}}
};

var agg = [
比赛,
查找,
项目
];

Register.aggregate(agg)
.then(.....)



尝试1



我以为我可以做这样的事情,但它仍会返回所有通知字段

  var project = {
$ project:{
_id:1,
userId :1,1,
accessToken:1,
count:{$ size: $ notifications},
notifications._id:1,
notifications .summaryId:1,
notifications.dateCreated:1,

通知:{
$ filter:{
输入: $ notifications,
如: item,
cond:dateCondition
},
}}
};



解决方案



我创建了另一个投影,将其添加到管道中:

  var project2 = {
$ project:{
_id:1,
userId:1,
accessToken:1,
count:{$ size: $ notifications},
notifications._id:1,
notifications.summaryId:1,
notifications.dateCreated:1,
notifications.dateProcessed:1,
}
};


var agg = [
比赛,
查找,
项目,
project2,
];

谢谢!

解决方案

https://stackoverflow.com/users/6635464/ngshravil-py 发现了



我创建了另一个投影:

  var project2 = {
$ project:{
_id:1,
userId:1,
accessToken:1,
count:{$ size: $ notifications},
notifications._id:1,
notifications.summaryId:1,
notifications.dateCreated:1,
notifications.dateProcessed:1,
}
};

然后将其添加到我的聚合管道中:



< pre class = lang-js prettyprint-override> var agg = [
匹配项,
查找,
项目,
project2,
];

已工作! -谢谢 https://stackoverflow.com/users/6635464/ngshravil-py


I am VERY close to getting what I want out of this query... but I only want SOME of the fields returned and right now it is returning all of them

NOTE: This is a refinement : I am now asking how to return only certain fields, while my similar question asks how to return the data between a start and end date

In addition, can somebody please please provide an answer using the MongoDB Playground with MY data sets so I can try it out... I can't quite figure out how to "name" the data sets so they work in the playground !

Register Schema

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RegisterSchema = new Schema({
    userId: {type: Schema.Types.ObjectId, required: true},
    accessToken: {type:String, required: true, default: null},
})
module.exports = Register = mongoose.model( 'register', RegisterSchema)

Here is some register data

[
  {
    "_id": "5eac9e815fc57b07f5d0d29f",
    "userId": "5ea108babb65b800172b11be",
    "accessToken": "111"
  },
  {
    "_id": "5ecaeba3c7b910d3276df839",
    "userId": "5e6c2dddad72870c84f8476b",
    "accessToken": "222"
  }
]

The next document contains data that is related to the Register schema via the accessToken

Notifications

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const NotificationSchema = new Schema({
    accessToken: {type:String, required: true},
    summaryId: {type:Number, required: true},
    dateCreated: {type: Date, default: Date.now},

    // I don't want these returned in the final results
    dontWantThis1: {type:Number, required: true},
    dontWantThis2: {type:Number, required: true},
})
module.exports = Notification = mongoose.model( 'notification', NotificationSchema)

Here is some notification data

[{
    "_id": "5ebf0390c719e60004f42e74",
    "accessToken": "111",
    "summaryId": 1111,
    "dontWantThis1": 61,
    "dontWantThis2": 62,
    "dateCreated": "2020-04-17T00:00:00.000+00:00" }, 
  {
    "_id": "6ebf0390c719e60004f42e76",
    "accessToken": "222",
    "summaryId": 2221,
    "dontWantThis1": 71,
    "dontWantThis2": 72,
    "dateCreated": "2020-04-18T00:00:00.000+00:00" },
  {
    "_id": "6ebf0390c719e60004f42e78",
    "accessToken": "111",
    "summaryId": 1112,
    "dontWantThis1": 611,
    "dontWantThis2": 622,
    "dateCreated": "2020-05-25T00:00:00.000+00:00" },
  {
    "_id": "6ebf0390c719e60004f42e80",
    "accessToken": "222",
    "summaryId": 2222,
    "dontWantThis1": 711,
    "dontWantThis2": 722,
    "dateCreated": "2020-05-26T00:00:00.000+00:00" }
]

Works, returns data between the two dates, but

This code returns everything, including the 'dontWantThis1' and 'dontWantThis2'

NOTE

I do not want the fields prefaced with 'dontWantThis' - but that is only to show which ones I don't want... I don't literally want to exclude fields prefaced with 'dontWantThis' ..... they could be named 'foo' or 'apple' or 'dog' they are just named that way to indicate that I don't want them


        // make sure the input dates are REALLY date objects
        // I only want to see notifications for the month of May (in this example)
        var dateStart = new Date('2020-05-01T00:00:00.000+00:00');
        var dateEnd = new Date('2020-05-30T00:00:00.000+00:00');     

        var match = {$match: { userId: mongoose.Types.ObjectId(userId) } };

        var lookup ={
            $lookup:
            {
                from: "my_Notifications",
                localField: "accessToken",
                foreignField: "accessToken",
                as: "notifications"
            }
        };

        var dateCondition = { $and: [
            { $gte: [ "$$item.dateCreated", dateStart ] },
            { $lte: [ "$$item.dateCreated", dateEnd ] }
          ]}  

        var project = {
            $project: {
                notifications: {
                    $filter: {
                    input: "$notifications",
                    as: "item",
                    cond: dateCondition
                    } } }
        };

        var agg = [
            match,
            lookup,
            project
        ];

        Register.aggregate(agg)
        .then( ..... )

Try 1

I thought I could do something like this, but it still returns ALL of the notification fields

        var project = {
            $project: {
                "_id": 1,
                "userId": 1,
                "accessToken":1,
                "count":{$size:"$notifications"},
                "notifications._id":1,
                "notifications.summaryId": 1,
                "notifications.dateCreated":1,

                notifications : {
                    $filter: {
                    input: "$notifications",
                    as: "item",
                    cond: dateCondition
                    },
            }}
        };

SOLUTION

I created another projection and added that to the pipeline:

        var project2 = {
            $project: {
                "_id": 1,
                "userId": 1,
                "accessToken":1,
                "count":{$size:"$notifications"},
                "notifications._id":1,
                "notifications.summaryId": 1,
                "notifications.dateCreated":1,
                "notifications.dateProcessed":1,
            }
        };


        var agg = [
            match,
            lookup,
            project,
            project2,
        ];

Thanks!!

解决方案

https://stackoverflow.com/users/6635464/ngshravil-py was spot on.

I created another projection:

        var project2 = {
            $project: {
                "_id": 1,
                "userId": 1,
                "accessToken":1,
                "count":{$size:"$notifications"},
                "notifications._id":1,
                "notifications.summaryId": 1,
                "notifications.dateCreated":1,
                "notifications.dateProcessed":1,
            }
        };

Then added it to my aggregation pipeline:

        var agg = [
            match,
            lookup,
            project,
            project2,
        ];

Worked ! -- thank you https://stackoverflow.com/users/6635464/ngshravil-py

这篇关于如何仅从Mongodb聚合返回某些字段($ project),同时还使用$ match,$ lookup和$ filter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆