在我的项目中,我有一个搜索栏,用户可以搜索其他用户。
我使用MongoDB作为我的数据库引擎,并在我的服务器的nodeJS上使用mongoose,到目前为止一切正常,除了一件事,我想按相关性排序结果。
想象一下,我有这个系列
{
"nombre" : "Ramiro",
"apellido" : "Garcilazo",
"empresa" : "PEMEX",
"tamano" : "Grande(250+)",
"sector" : "Servicios",
"giro" : "Sustancias Químicas",
"actividad" : "Venta de petroquimicos",
"estado" : "Jalisco"
}
{
"nombre" : "Luis",
"apellido" : "Alberto",
"empresa" : "GanaMex",
"tamano" : "Mediana (51-250)",
"sector" : "Construccion",
"giro" : "Agricultura, Ganaderia y Pesca",
"actividad" : "Graneros",
"estado" : "Aguascalientes"
}
{
"nombre" : "Ramon",
"apellido" : "Corona",
"empresa" : "CoronMex",
"tamano" : "Micro (1-10)",
"sector" : "Construccion",
"giro" : "Textiles, Prendas y Productos de Cuero",
"actividad" : "Venta de tiendas de campaña",
"estado" : "Ciudad de mexico"
}
{
"nombre" : "Joe",
"apellido" : "Doe",
"empresa" : "Apple inc",
"tamano" : "Micro (1-10)",
"sector" : "Construccion",
"giro" : "Alimentos y Bebidas",
"actividad" : "Ejemplo",
"estado" : "Veracruz"
}
{
"nombre" : "John",
"apellido" : "Smith",
"empresa" : "Google inc",
"tamano" : "Micro (1-10)",
"sector" : "Bienes",
"giro" : "Agricultura, Ganaderia y Pesca",
"actividad" : "XYZ",
"estado" : "Aguascalientes"
}
{
"nombre" : "foo",
"apellido" : "bar",
"empresa" : "foobar inc.",
"tamano" : "Mediana (51-250)",
"sector" : "Servicios",
"giro" : "Alimentos y Bebidas",
"actividad" : "foo-bar",
"estado" : "Aguascalientes"
}
{
"nombre" : "Jonathan",
"apellido" : "Ceja",
"empresa" : "It4Pymes",
"tamano" : "Grande(250+)",
"sector" : "Bienes",
"giro" : "Mineria, Petroleó y Gas",
"actividad" : "asdf",
"estado" : "Baja California"
}
我当前的查询看起来像这样
export function buscarProveedor(req, res) {
var regTerms = [];
//creates an RegExp array of all the terms the user searched
var terms = req.body.term.split(" ");
for (var i = 0; i < terms.length; i++) {
regTerms.push(new RegExp(terms[i], 'i'));
}
//creates a single RegExp for all the term
var regTerm = new RegExp(req.body.term, 'i');
User.find({
$and: [{
//any of this that matches
$or: [{
nombre: regTerm
}, {
empresa: regTerm
}, {
sector: {
$in: regTerms
}
}, {
giro: {
$in: regTerms
}
}, {
estado: {
$in: regTerms
}
}, {
actividad: {
$in: regTerms
}
}, {
tags: {
$in: regTerms
}
}]
}, {
//ignore this, just checks if is not another type of user
empresa: {
$exists: true
}
}, {
//checks that doesn't gets the user that made the query
_id: {
$ne: req.body.id
}
}]
}, '_id nombre empresa')
.then(user => {
//returns it to my front-end
res.json(user).end();
});
}
所以,例如在我的搜索栏中,我将&#34; Construccion&#34;,响应将是
{
"_id": 0
"nombre" : "Luis",
"empresa" : "GanaMex"
}
{
"_id": 1
"nombre" : "Ramon",
"empresa" : "CoronMex",
}
{
"_id": 2
"nombre" : "Joe",
"empresa" : "Apple inc",
}
但是如果我把&#34; Construccion Textiles&#34;,即使id 1与2个术语相匹配,我也会得到相同的结果。
我想知道它有多少匹配,所以我可以通过相关性来订购它,把最多的匹配放在最上面。
我可以通过查询来实现,或者我必须在之后操作数据, 我真的不知道,我以前从未见过这个问题。
感谢。
编辑:好的,我使用$ match和$ group来做这件事,但仍然没有做我想要的,我用过它。
export function buscarProveedorAvansado(req, res) {
var regTerms = [];
var terms = req.body.term.split(" ");
for (var i = 0; i < terms.length; i++) {
regTerms.push(new RegExp(terms[i], 'i'));
}
var regTerm = new RegExp(req.body.term, 'i');
User.aggregate([{
$match: {
$and: [{
$or: [{
nombre: regTerm
}, {
empresa: regTerm
}, {
sector: {$in: regTerms}
}, {
giro: {$in: regTerms}
}, {
estado: {$in: regTerms}
}, {
actividad: {$in: regTerms}
}, {
tags: {$in: regTerms}
}]
}, {
empresa: {$exists: true}
}, {
_id: {
$ne: req.body.id
}
}]
}
}, {
$group: {
"_id" : "$_id",
"nombre" : {$max: "$nombre"},
"empresa": {$max: "$empresa"},
count: {
$sum: 1
}
}
}]).then(user => {
console.log(user);
res.json(user).end();
});
}
我使用术语&#34; Construccion&#34;
得到这个结果[{
"_id": 0
"nombre" : "Luis",
"empresa" : "GanaMex",
"count": 1
}
{
"_id": 1
"nombre" : "Ramon",
"empresa" : "CoronMex",
"count": 1
}
{
"_id": 2
"nombre" : "Joe",
"empresa" : "Apple inc",
"count": 1
}]
如果我使用术语&#34; Construccion Textiles&#34;
,我会得到完全相同的结果我尝试了几件事,在$ sum上使用$ cond:
$sum:[{
$cond: {
if: {
nombre: regTerm
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
empresa: regTerm
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
sector: {
$in: regTerms
}
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
giro: {
$in: regTerms
}
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
giro: {
$in: regTerms
}
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
estado: {
$in: regTerms
}
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
nombre: regTerm
},
then: 1,
else: 0
}
}, {
$cond: {
if: {
nombre: regTerm
},
then: 1,
else: 0
}
}]
获取mongo错误。
我认为$和$和$的问题是因为技术上最终是单一的,我不知道是否有解决方法。
我在这里错过了明显的吗?
答案 0 :(得分:1)
您可以使用匹配功能,该功能会在您的查询撤回的所有文档中执行计数。
https://docs.mongodb.com/manual/reference/operator/aggregation/match/#perform-a-count