在mongoDB中执行文本搜索,并查找集合中

时间:2016-06-19 11:04:32

标签: javascript node.js mongodb express

我希望建立一种搜索一系列旅行的方法。搜索查看旅行是否包含传递的城市名称(从和到达位置)。每个旅行模型都具有创建条目的用户的ID。查询可能会在集合中返回0或100个项目。我需要在搜索结果中显示有关用户的数据。我最好的方式是搜索旅行信息并获取用户信息。

结果中的每次旅行可能会有不同的用户。

我已经考虑过在旅行模型中嵌入用户信息,但是每次用户信息发生变化时我都必须有一个更新信息的策略。用户(创建者)关系之旅将始终是一对一的。目前我只嵌入用户ID。这适用于我一次查询一次旅行但不搜索的情况。

当前查询:在文本中寻找匹配

module.exports = function(app) {
    app.get('/search', function(req, res) {
    var search = req.query;
    var query = {};

    if(search.origin) {
        query.origin = {
            $regex: search.origin,
            $options: 'i',
        };
    }

    if(search.destination) {
        query.destination = {
            $regex: search.destination,
            $options: 'i',
        };
    }

    Trip.find(query, function(err, trips) {
        if(err) return res.json( err );

        return res.json(trips);            
    });
});

旅行模式:

var TripSchema = mongoose.Schema({
    user: {
        type: Schema.Types.ObjectId,
        required: true
    },
    origin: {
        type: String,
        required: true
    },
    destination: {
        type: String,
        required: true
    },
    departing: {
        type: Date,
        required: true
    },
    returning: {
        type: Date
    },
});

用户模型:

var UserSchema = mongoose.Schema({
    name: {
        type: String
    },
    username: {
        type: String
    },
    password: {
        type: String,
    }

});

1 个答案:

答案 0 :(得分:0)

我不确定我是否做得对,但我最终做了这样的事情。首先,我根据搜索字符串从我的数据库中获取行程。搜索基于旅行的起点和终点。一旦我有了旅行列表,我就会遍历数组并获取每个用户的ID并将其推送到另一个数组中。我接受了那个数组,并使用db.model.find()方法和$in运算符来查找数组中的用户。

因为我需要每次旅行都有一个用户对象,所以我在旅行中再次迭代,并将用户obj分配给旅程。

由于对象mongoose返回的类型,我不得不对JSON进行一些转换。我不能只分配一个新的财产。我使用toJSON()方法将其转换为JSON。

如果有人知道更好的方法或有任何想法如何改进下面的代码,那么任何建设性的反馈都会受到欢迎。

app.get('/search', function(req, res) {
    if(!req.query.origin || !req.query.destination){
        return res.json({trips: []});
    }

    var search = req.query;
    var query = {};

    if(search.origin) {
        query.origin = {
            $regex: search.origin,
            $options: 'i',
        };
    }

    if(search.destination) {
        query.destination = {
            $regex: search.destination,
            $options: 'i',
        };
    }

    Trip.find(query, function(err, trips) {
        if(err) return res.json(err);

        var userIds = [];

        //get user ids from trip
        trips.forEach(function(trip) {
            userIds.push(mongoose.Types.ObjectId(trip.user));
        });

        var user = User.find({
            '_id': { $in: userIds}
        });

        user.select('id name');
        user.exec(function (err, users) {
            if (err) return res.json(err);

            var jsonTrips = [];
            var currentTrip;

            trips.forEach(function(trip) {
                currentTrip = trip.toJSON();
                currentTrip.user = findTripUser(trip.user, users);
                jsonTrips.push(currentTrip);
            });

            return res.json(jsonTrips);  
        });   
    });
});

function findTripUser(tripId, users) {
    var user;
    for(var i = 0; i < users.length; i++) {
        if(JSON.stringify(users[i]._id)=== JSON.stringify(tripId)) {
            user = users[i];
            break;
        } 
    }

    return user.toJSON();
}