在mongoDB中执行文本搜索,并查找集合中每个项目的参考文档

时间:2022-02-25 16:59:35

I am looking to build a way to search through a collection of trips. The search looks at whether the trip contains the passed city names (from and to location). Each trip model has the id of the user who created the entry. The query may return 0 or 100 items in the collection. I need to display data about the user in the search results. What is the best way for me to search the trip information and also get the user information.

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

Each trip in the results may have a different user.

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

I have thought about embedding the user information in the trip model but then I have to have a strategy for updating the information every time the user information changes. The trip to user(creator) relationship will always be one-to-one. Currently I am only embedding the user ID. This works fine for when I query one trip at a time, but not for a search.

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

Current Query: Looking for a match in the text

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

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);            
    });
});

Trip Model:

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
    },
});

User Model:

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

});

1 个解决方案

#1


0  

I am not really sure if I did this right, but I ended up doing something like this. First I get the trips from my db based on the search string. The search is based on an origin and destination for a travel trip. Once I have the list of trips I iterate through the array and get the ID of each user and push it into another array. I take that array and I use the db.model.find() method with the $in operator to find the users from the array.

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

Because I need each trip to have a user object I iterate one more time through the trips, and assign the user obj to the trip.

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

I had to do some conversions to JSON because of the type of object mongoose returns. I can't just assign a new property. I converted it to JSON using the toJSON() method.

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

If someone knows a better approach or have any ideas how to improve the code bellow, any constructive feedback is welcomed.

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

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();
}

#1


0  

I am not really sure if I did this right, but I ended up doing something like this. First I get the trips from my db based on the search string. The search is based on an origin and destination for a travel trip. Once I have the list of trips I iterate through the array and get the ID of each user and push it into another array. I take that array and I use the db.model.find() method with the $in operator to find the users from the array.

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

Because I need each trip to have a user object I iterate one more time through the trips, and assign the user obj to the trip.

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

I had to do some conversions to JSON because of the type of object mongoose returns. I can't just assign a new property. I converted it to JSON using the toJSON() method.

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

If someone knows a better approach or have any ideas how to improve the code bellow, any constructive feedback is welcomed.

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

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();
}