猫鼬没有带来任何结果

时间:2018-05-21 15:29:27

标签: node.js express mongoose

我试图在mongoose中构建一种复杂的查询,我的问题是这个查询可以接收的所有参数都是非强制性的,这给我带来了问题。现在我这样做了:

let query = {
            publicationType: req.body.searchParams.publicationType
        };
        if (req.body.searchParams.address) {
            query.address = {};
            if (req.body.searchParams.address.city) {
                query.address.city = req.body.searchParams.address.city;
            }
        }
        try {
            const dwellings = await model.Dwelling.find({
                $and: [{$or: [{publicationType: req.body.searchParams.publicationType}]},
                    {
                        $or: [{
                            address: [query.address]
                        }]
                    }]
            }).lean().exec();
            console.log(dwellings);
            res.send({dwellings});
        } catch (err) {
            next(err);
        }
    });

这是试试城市参数是否有效,如果我只按发布类型搜索我得到了想要的结果,如果我添加城市我得到0结果,即使我应该得到更多,我调试mongoose看看查询是如何构建的,它是这样的:

Mongoose: dwelling.find({ '$and': [ { '$or': [ { publicationType: 'Venta' } ] }, { '$or': [ { address: { '$in': [ { city: 'La Plata' } ] } } ] } ] }, { fields: {} })
[]

2 个答案:

答案 0 :(得分:1)

在您的代码中,您构建$and expression两个$or expressions ,但每个 $或表达式每个只有一个参数,所以你是有效构建此 $和 find表达式(请注意,我正在使用下面的mongo shell语法):

db.dwellings.find({ 
   '$and': [ 
       { publicationType: 'Venta' }, 
       { address: { '$in': [ { city: 'La Plata' } ] } } 
   ]
});

...单词:“查找带有publicationType Venta address.city La Plata的住所。

  

如果我添加城市我得到0结果,即使我应该得到更多

因为你提到你希望在添加address.city时获得更多结果我怀疑你真的希望顶级表达式为$or而不是$and,如下所示:

db.dwellings.find({ 
   '$or': [ 
       { publicationType: 'Venta' }, 
       { address: { '$in': [ { city: 'La Plata' } ] } } 
   ]
});

您可能希望在mongo shell中对您的查询进行更多实验,然后再将其表示为代码。如果您的工作站上碰巧有Docker,我发现在容器中运行mongo是一种在开发过程中对事物进行原型设计的有用方法,例如:

docker run --name mongo -d mongo:3.7
# after mongo is up and running...
docker exec -it mongo mongo

在交互式mongo shell中,您可以插入文档以进行测试并使用find表达式进行实验,例如:

use stackoverflow;
dwell1 = { publicationType: 'Venta', address: { city: 'Somewhere' } };
dwell2 = { publicationType: 'Something', address: { city: 'La Plata' } };
db.dwellings.insert(dwell1);
db.dwellings.insert(dwell2);

# Try results of $and
db.dwellings.find({ '$and': [ 
   { publicationType: 'Venta' }, 
   { address: { '$in': [ { city: 'La Plata' } ] } } 
]  });

# ... compare to results of $or
db.dwellings.find({ '$or': [ 
   { publicationType: 'Venta' }, 
   { address: { '$in': [ { city: 'La Plata' } ] } } 
]  });

...一旦您插入了一些文档进行测试,请确认您的$and中是否需要$orfind表达。

答案 1 :(得分:0)

所以有了画笔Maclnnis的指导我想出了如何让它至少起作用

const query = {};
        if (req.body.searchParams.publicationType !== '') {
            query['publicationType'] = req.body.searchParams.publicationType;
        }
        if (req.body.searchParams.address) {
            if (req.body.searchParams.address.streetNumber !== undefined) {
                query['address.streetNumber'] = req.body.searchParams.address.streetNumber;
            }
            if (req.body.searchParams.address.streetName !== undefined) {
                query['address.streetName'] = req.body.searchParams.address.streetName;
            }
            if (req.body.searchParams.address.city !== undefined) {
                query['address.city'] = req.body.searchParams.address.city;
            }
            if (req.body.searchParams.address.state !== undefined) {
                query['address.state'] = req.body.searchParams.address.state;
            }
            if (req.body.searchParams.address.country !== undefined) {
                query['address.country'] = req.body.searchParams.address.country;
            }
            if (req.body.searchParams.address.zip !== undefined) {
                query['address.zip'] = req.body.searchParams.address.zip;
            }
        }
        if (req.body.searchParams.price) {
            if (req.body.searchParams.price.min !== undefined) {
                query['price'] = {$gt: req.body.searchParams.price.min};
            }
            if (req.body.searchParams.price.max !== undefined) {
                query['price'] = {$lt: req.body.searchParams.price.max};
            }
        }
        try {
            const dwellings = await model.Dwelling.find({
                '$and': [
                    query
                ]
            }).lean().exec();
            console.log(dwellings);
            res.send({dwellings});
        } catch (err) {
            next(err);
        }

这可以优化吗?