我认为,你能做的最好的事情就是Text Search。
答案 1:
1.1。第一步
您必须在您的集合上创建文本索引才能执行文本搜索。
创建文本索引
db.user.createIndex({"name":"text", "email": "text"})
db.vehicle.createIndex({"name": "text", "color": "text"})
我们必须在两个集合上创建文本索引,因为我们想对两个集合执行文本搜索。
*
注意:
由于我们正在对来自 User 的“name”、“email”和来自 Vehicle 的“name”、“color”创建文本索引,因此您只能对各自集合中的这四个字段执行文本搜索。
您可以为字段分配权重,以便根据文本分数对结果进行排序。 (您必须在创建索引时执行此操作)。
*
1.2。第二步
(我假设您在这里使用的是 Javascript 和 mongoose。)
db.collection("users").aggregate({$match:{$text: {$search: "pink"}}},
(err, userData: any)=>{
if(err){
return err;
}
if(userdata.length){
let vehicleIds = userData.map((user) => mongoose.Types.ObjectId(user.vehicleId));
db.collection("vehicles").aggregate({$match:{$text:{$search:"pink", _id: {$in: vehicleIds}}}}, (err, vehicleData)=>{
//this will be your vehicle details
})
})
}else{
console.log("no Data found");
}
*
问题使用这种方法时,您必须触发两个查询,因为 文本搜索 中的 restrictions 以及集合上文本索引的额外开销。
好事是你有很多方法来执行搜索,你可以根据文本分数的相关性对结果进行排序,它比正则表达式快,而且你会得到更好的结果,你会得到词干,你会得到停用词(请参考给出的链接)。
*
答案 2:
你可以使用正则表达式
db.collection("users").aggregate({$match:{$or:[{name:{$regex: /pink/}}, {email:{$regex: /pink/}}]}},
{$lookup:{from:"vehicles", localField:"vehicleId", foreignFild:"_id", as:"vehicleDetail"}},
{$unwind:{path:"$vehicleDetail"}},
{$match:{$or:[{name:{$regex:/pink/}},{color:{$regex:/pink/}}]}}
(err, data)=>{
})
答案 3:
如果您不想选择上述选项,也可以触发普通查询
db.collection("users").aggregate({$match:{$or:[{name:{$regex: /pink/}}, {email:{$regex: /pink/}}]} },
{$lookup:{from:"vehicles", localField:"vehicleId", foreignFild:"_id", as:"vehicleDetail"}},
{$unwind:{path:"$vehicleDetail"}},
{$match:{$or:[{name:{$regex:/pink/}},{color:{$regex:/pink/}}]}}
(err, data)=>{
})
希望这会有所帮助。 :-)
如果我在任何地方错了,请纠正我。 :-)