Búsqueda difusa en MongoDB

Mehvish Ashiq 16 febrero 2024
  1. ¿Qué es la búsqueda difusa?
  2. Crear una colección de muestra en MongoDB
  3. Utilice el operador $regex para realizar una búsqueda aproximada en MongoDB
  4. Use la consulta $text para realizar una búsqueda aproximada en MongoDB
  5. Use la biblioteca Fuse.js de JavaScript para realizar búsquedas aproximadas en MongoDB
Búsqueda difusa 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.

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook