我目前正在构建一个Web应用程序,但偶然发现了过去12个小时无法解决的问题。

我正在研究一种基本的get方法,在该方法中我尝试检索员工正在工作的某些工作位置(即收银员,业务员)(客户端工作正常)。

WorkPosition的猫鼬模型是这样的(models / work-position.js):

var mongoose = require('mongoose');
var User = require('./user');
var Schema = mongoose.Schema;
var schema = new Schema ({
    workplace : {type: String, required: true},
    type : {type: String, required: true},
    status : {type: String, required: true},
    color : {type: String, required: true},
    employees: [{type: Schema.Types.ObjectId, ref:'User'}]
 });

module.exports = mongoose.model('WorkPosition', schema);


我的get方法(routes / work-position.js):

var express = require('express');
var router = express.Router();
var jwt = require('jsonwebtoken');
var User = require('../models/user');
var mongoose = require('mongoose');

var WorkPosition = require('../models/work-position');

router.get('/:userId', function(req, res, next) {
    const userId = req.params.userId;
    WorkPosition.find({employees: {$elemMatch : {$eq: userId}}})
        .exec(function(err, workPositions) {
            if(err) {
                return res.status(500).json({
                    title: 'an error has occurred',
                    error: err
                });
            }
            console.log(userId);
            console.log(workPositions);
            res.status(200).json({
                message: 'Success',
                obj: workPositions
            });
        });
});


当我尝试使用$ elemMatch方法时,就会出现问题。上面的代码,当WorkPosition.find行更改为

WorkPosition.find()


没有任何条件(

{employees: {$elemMatch : {$eq: userId}}}


)内部,我可以成功检索所需的WorkPosition文档。

但是,我只想检索WorkPosition中“员工”字段与我从req.params收到的“ userId”相匹配的WorkPosition文档。因此,我搜索了mongodb / mongoose API(http://mongoosejs.com/docs/api.html#query_Query-elemMatch

在这里找到$ elemMatch方法。

在mongodb shell中,当我这样做时

db.workpositions.find({"employees": { $elemMatch : {$eq: "596823efbac11d1978ba2ee9"}}})


其中“ 5968 ....”是userId,我可以成功查询WorkPosition文档。

通过此命令,我可以验证我的逻辑是正确的,并且使用mongodb native shell命令可以获取所需的文档。

但是,当我尝试将相同的逻辑转换为Mongoose API时,即:

WorkPosition.find().elemMatch('employees', {$eq : userId})


我得到一个空数组,并添加行

mongoose.set('debug', function (coll, method, query, doc) {
    console.log(coll + " " + method + " " + JSON.stringify(query) + " " + JSON.stringify(doc));
});


在/app.js中,我能够看到猫鼬查询将什么转换为本地mongodb命令,即:

workpositions find {"employees":{"$elemMatch":{"$eq":"596823efbac11d1978ba2ee9"}}} {"fields":{}}


。集合(工作位置),方法(查找),要查找的数组(员工)以及所有内容均已正确翻译为本地mongodb命令EXCEPT

"$eq"


。成功运行的shell命令与我的代码中的mongoose命令之间的唯一区别是'$ eq'周围的引号引起来。

贝壳:

db.workpositions.find({"employees": { $elemMatch : {$eq: "596823efbac11d1978ba2ee9"}}})


猫鼬:

db.workpositions.find({"employees": { $elemMatch : {"$eq": "596823efbac11d1978ba2ee9"}}})


我似乎找不到消除这些多余引号的方法(我相信这是问题的原因)。我尝试将本地命令与猫鼬一起使用:

mongoose.connection.db.workpositions.find(.....)


但这也会导致错误。

通过猫鼬使用elemMatch的正确方法是什么?谁能启发我如何使用它?我想尽了一切办法,但似乎无法克服这个问题。

我正在考虑更改WorkPosition.employees字段,以使其保留实际的用户(不仅是userIds),而且我可以解析与Mongoose elemMatch API完全匹配的其他信息。但是,我相信这会浪费大量的数据库空间,因为每个WorkPosition必须携带一组用户。

为了在用户和工作位置之间具有正确的关系,elemMatch是我的项目中的要求。我将不胜感激任何帮助!

最佳答案

比较mongodb ObjectIds时,请在$ eq数组运算符周围使用mongoose.Types.ObjectId,然后可以使用$ elemMatch运算符检索与条件匹配的第一个文档。


  $ elemMatch:{$ eq:mongoose.Types.ObjectId(userId)}

关于node.js - Mongoose elemMatch返回一个空数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45954121/

10-09 20:17