2016-08-18 2 views
2

В моем проекте у меня есть панель поиска, где пользователь может искать других пользователей.Как узнать, сколько совпадений имеет запрос mongodb

Я использую MongoDB в качестве моего механизма базы данных и mongoose на nodeJS для своего сервера, и до сих пор все работает, кроме одного, я хотел бы заказать результаты по релевантности.

Представьте меня есть эта коллекция

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

Так, например, в моей строке поиска я ставлю «Строящийся», то ответ будет

{ 
    "_id": 0 
    "nombre" : "Luis", 
    "empresa" : "GanaMex" 
} 
{ 
    "_id": 1 
    "nombre" : "Ramon", 
    "empresa" : "CoronMex", 
} 
{ 
    "_id": 2 
    "nombre" : "Joe", 
    "empresa" : "Apple inc", 
} 

Но если бы я поставил «Construccion Textiles», я получил бы тот же точный результат, хотя t он id 1 соответствовал двум условиям.

Я хотел бы знать, сколько совпадений у него есть, поэтому я могу заказать его по релевантности, поставив на верхнюю часть, которая получила больше совпадений.

Могу ли я достичь этого с помощью запроса, или мне нужно манипулировать данными после, Я честно понятия не имею, и я не видел, чтобы это задавали раньше.

Спасибо.


Edit: Ok я использовал $ спичку и $ группу, чтобы сделать это, но все еще havn't сделал то, что я хочу, я использовал это.

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

И я получаю этот результат, используя термин «Строящийся»

[{ 
    "_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 
}] 

И снова я получить тот же результат, если я использую термин «Строящийся Textiles»

Я пытался несколько вещей, используя $ 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.

Я понял, что проблема с $ и $ и $ или с тех пор, как технически в конце является единственной истиной, и я не знаю, есть ли обходной путь.

Я пропустил здесь очевидное место?

ответ

1

Вы можете использовать функцию соответствия, которая выполняет подсчет всех документов, которые ваш запрос оттащил.

https://docs.mongodb.com/manual/reference/operator/aggregation/match/#perform-a-count

+0

Хорошо, я попытался использовать пример по ссылке. [PasteBin] (http://pastebin.com/9DpuK4ZN), и это дало мне это в результате '[{_id: null, count: 3}]' Как я могу получить каждый документ отдельно и считать каждый матч , можете ли вы мне помочь? – Mockingguy

Смежные вопросы