Búsqueda difusa en MongoDB
- ¿Qué es la búsqueda difusa?
- Crear una colección de muestra en MongoDB
-
Utilice el operador
$regex
para realizar una búsqueda aproximada en MongoDB -
Use la consulta
$text
para realizar una búsqueda aproximada en MongoDB -
Use la biblioteca
Fuse.js
de JavaScript para realizar búsquedas aproximadas en MongoDB
Hoy, discutiremos la búsqueda difusa y cómo podemos hacer una búsqueda difusa usando MongoDB.
Comenzaremos usando el operador $regex
y la consulta $text
. Además, avanzaremos hacia el aprendizaje del uso de una biblioteca de JavaScript llamada Fuse.js
para realizar una búsqueda aproximada en los documentos.
¿Qué es la búsqueda difusa?
Con la búsqueda aproximada, podemos buscar un texto que no coincida exactamente pero que coincida estrechamente con el término. Es útil encontrar resultados relevantes incluso cuando los términos de búsqueda están mal escritos.
Por ejemplo, Google nos muestra varias páginas web relevantes para nuestro término buscado incluso cuando está mal escrito. El uso de expresiones regulares (también llamadas expresiones regulares) también es un enfoque muy beneficioso y que ahorra tiempo para implementar una búsqueda difusa.
Crear una colección de muestra en MongoDB
Comenzaremos desde el nivel básico hasta el avanzado para aprender la búsqueda difusa. Para practicarlo, vamos a crear una colección de muestra llamada collection_one
que tiene un campo para cada documento, que es el name
.
El _id
se crea automáticamente; no tenemos que crear eso. Puede utilizar las siguientes consultas para hacer lo mismo.
Código de ejemplo:
> db.createCollection('collection_one')
> db.collection_one.insertMany([
{ name : 'Mehvish Ashiq'},
{ name : 'Jennifer Johnson'},
{ name : 'Natalie Robinson'},
{ name : 'John Ferguson'},
{ name : 'Samuel Patterson'},
{ name : 'Salvatore Callahan'},
{ name : 'Mikaela Christensen'}
])
> db.collection_one.find()
Producción :
{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddaf"), "name" : "Jennifer Johnson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb0"), "name" : "Natalie Robinson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb1"), "name" : "John Ferguson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb3"), "name" : "Salvatore Callahan" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }
Utilice el operador $regex
para realizar una búsqueda aproximada en MongoDB
Código de ejemplo:
> db.collection_one.find({"name": /m/})
Producción :
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
En este código, realizamos una búsqueda aproximada en el campo name
y recuperamos todos los documentos donde el campo name
contiene la letra m
.
Como puede ver, solo tenemos un registro que contiene la letra m
, pero hay dos documentos más que comienzan con M
(letra mayúscula). Para manejar esto, podemos usar el modificador i
de la siguiente manera, que realiza la búsqueda sin distinción entre mayúsculas y minúsculas.
Código de ejemplo:
> db.collection_one.find({"name": /m/i})
Producción :
{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }
Mostró que tener una expresión regular correctamente diseñada es muy importante; de lo contrario, podemos obtener resultados engañosos. También podemos hacer lo mismo de la siguiente manera.
Código de ejemplo (búsqueda que no distingue entre mayúsculas y minúsculas):
> db.collection_one.find({'name': {'$regex': 'm','$options': 'i'}})
Producción :
{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }
Del mismo modo, podemos obtener todos los documentos donde el name
termina en una combinación de dos letras como on
.
Código de ejemplo:
> db.collection_one.find({name:{'$regex' : 'on$', '$options' : 'i'}})
Producción :
{ "_id" : ObjectId("62939a37b3a0d806d251ddaf"), "name" : "Jennifer Johnson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb0"), "name" : "Natalie Robinson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb1"), "name" : "John Ferguson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
Use la consulta $text
para realizar una búsqueda aproximada en MongoDB
La consulta $text
no funcionará en nuestra colección de muestra llamada collection_one
porque no tiene el índice de texto. Entonces, creamos el índice de la siguiente manera.
Código de ejemplo:
> db.collection_one.createIndex({name:"text"});
La declaración anterior también creará la colección especificada si aún no existe. Recuerda que podemos crear un índice en uno o varios campos separados por una coma.
Vea el siguiente ejemplo.
db.collection_name.createIndex({name:"text", description:"text"});
Una vez que se crea el índice, podemos hacer una búsqueda aproximada como se indica a continuación.
Código de ejemplo:
> db.collection_one.find({ $text: { $search: "Mehvish" } } )
Producción :
{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
Use la biblioteca Fuse.js
de JavaScript para realizar búsquedas aproximadas en MongoDB
Código de ejemplo (el código del archivo fuzzysearch.js
):
const Fuse = require('fuse.js')
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/';
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db('FuseFuzzySearch');
var personObj = [
{name: 'Mehvish Ashiq'}, {name: 'Jennifer Johnson'},
{name: 'Natalie Robinson'}, {name: 'John Ferguson'},
{name: 'Samuel Patterson'}, {name: 'Salvatore Callahan'},
{name: 'Mikaela Christensen'}
];
dbo.collection('person').insertMany(personObj, function(err, res) {
if (err) throw err;
});
const options = {includeScore: true, keys: ['name']}
const fuse = new Fuse(personObj, options);
const result = fuse.search('jahson');
console.log(result);
db.close();
});
Producción :
[
{
item: { name: 'Jennifer Johnson', _id: 6293aa0340aa3b21483d9885 },
refIndex: 1,
score: 0.5445835311565898
},
{
item: { name: 'John Ferguson', _id: 6293aa0340aa3b21483d9887 },
refIndex: 3,
score: 0.612592665952338
},
{
item: { name: 'Natalie Robinson', _id: 6293aa0340aa3b21483d9886 },
refIndex: 2,
score: 0.6968718698752637
},
{
item: { name: 'Samuel Patterson', _id: 6293aa0340aa3b21483d9888 },
refIndex: 4,
score: 0.6968718698752637
}
]
En este ejemplo de código, primero importamos la biblioteca fuse.js
. A continuación, nos conectamos a MongoDB.
Si no está conectado por algún motivo, arroja un error. De lo contrario, cree una base de datos llamada FuseFussySearch
.
Luego, crea un objeto llamado personObj
que contenga todos los documentos que queremos insertar en la colección person
. Se generará un error si hay algún problema al insertar los datos.
Cree el objeto de Fuse
, pase la matriz de objetos personObj
y options
que tienen keys
e includeScore
para realizar la búsqueda aproximada y obtener los resultados, como se indicó anteriormente.
Aquí, las teclas
especifican los campos en los que se realizará la búsqueda. El includeScore
es opcional, pero es mejor tenerlo porque indica el puntaje coincidente.
Si es 0
, el programa encuentra la coincidencia perfecta, mientras que una puntuación de 1
muestra la falta de coincidencia completa. Puedes encontrar todas las opciones aquí.
Finalmente, no olvides cerrar la conexión. Hay muchas otras bibliotecas que también puede explorar.