MongoDB의 퍼지 검색

Mehvish Ashiq 2024년2월16일
  1. 퍼지 검색이란
  2. MongoDB에서 샘플 컬렉션 생성
  3. $regex 연산자를 사용하여 MongoDB에서 퍼지 검색 수행
  4. $text 쿼리를 사용하여 MongoDB에서 퍼지 검색 수행
  5. JavaScript의 Fuse.js 라이브러리를 사용하여 MongoDB에서 퍼지 검색 수행
MongoDB의 퍼지 검색

오늘은 퍼지 검색과 MongoDB를 사용하여 퍼지 검색을 수행하는 방법에 대해 설명합니다.

$regex 연산자와 $text 쿼리를 사용하여 시작하겠습니다. 또한 Fuse.js라는 JavaScript 라이브러리를 사용하여 문서에서 퍼지 검색을 수행하는 방법을 배우도록 하겠습니다.

퍼지 검색이란

퍼지 검색을 사용하면 정확히 일치하지는 않지만 용어와 거의 일치하는 텍스트를 검색할 수 있습니다. 검색어의 철자가 틀린 경우에도 관련성 높은 결과를 찾는 데 유용합니다.

예를 들어, 구글은 우리가 검색한 용어와 관련된 다양한 웹 페이지를 잘못 입력해도 보여준다. 정규 표현식(regex라고도 함)을 사용하는 것은 퍼지 검색을 구현하기 위한 매우 유익하고 시간을 절약하는 접근 방식이다.

MongoDB에서 샘플 컬렉션 생성

퍼지 검색을 배우기 위해 기초부터 고급 레벨까지 시작합니다. 이를 연습하기 위해 name이라는 모든 문서에 대해 하나의 필드가 있는 collection_one이라는 샘플 컬렉션을 만들어 보겠습니다.

_id가 자동으로 생성됩니다. 우리는 그것을 만들 필요가 없습니다. 다음 쿼리를 사용하여 동일한 작업을 수행할 수 있습니다.

예제 코드:

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

출력:

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

$regex 연산자를 사용하여 MongoDB에서 퍼지 검색 수행

예제 코드:

> db.collection_one.find({"name": /m/})

출력:

{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }

이 코드에서 name 필드에 대해 퍼지 검색을 수행하고 name 필드에 문자 m이 포함된 모든 문서를 검색했습니다.

보시다시피 m 문자가 포함된 레코드는 하나만 있지만 M(대문자)으로 시작하는 문서가 두 개 더 있습니다. 이를 처리하기 위해 대소문자를 구분하지 않는 검색을 수행하는 i 수정자를 다음과 같이 사용할 수 있습니다.

예제 코드:

> db.collection_one.find({"name": /m/i})

출력:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }

올바르게 설계된 정규 표현식을 갖는 것이 매우 중요하다는 것을 보여주었습니다. 그렇지 않으면 잘못된 결과를 얻을 수 있습니다. 다음과 같은 방법으로도 똑같이 할 수 있습니다.

예제 코드(대소문자 구분 없는 검색):

> db.collection_one.find({'name': {'$regex': 'm','$options': 'i'}})

출력:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }

유사하게, name이 두 글자의 조합으로 끝나는 모든 문서를 on으로 가져올 수 있습니다.

예제 코드:

> db.collection_one.find({name:{'$regex' : 'on$', '$options' : 'i'}})

출력:

{ "_id" : ObjectId("62939a37b3a0d806d251ddaf"), "name" : "Jennifer Johnson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb0"), "name" : "Natalie Robinson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb1"), "name" : "John Ferguson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }

$text 쿼리를 사용하여 MongoDB에서 퍼지 검색 수행

$text 쿼리는 collection_one이라는 샘플 컬렉션에 텍스트 인덱스가 없기 때문에 작동하지 않습니다. 따라서 다음과 같이 인덱스를 생성합니다.

예제 코드:

> db.collection_one.createIndex({name:"text"});

위의 명령문은 지정된 컬렉션이 이미 존재하지 않는 경우에도 생성합니다. 쉼표로 구분된 하나 이상의 필드에 인덱스를 생성할 수 있음을 기억하십시오.

다음 예를 참조하십시오.

db.collection_name.createIndex({name:"text", description:"text"});

인덱스가 생성되면 아래와 같이 퍼지 검색을 수행할 수 있습니다.

예제 코드:

> db.collection_one.find({ $text: { $search: "Mehvish" } } )

출력:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }

JavaScript의 Fuse.js 라이브러리를 사용하여 MongoDB에서 퍼지 검색 수행

예제 코드(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();
});

출력:

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

이 코드 예제에서는 먼저 fuse.js 라이브러리를 가져왔습니다. 다음으로 MongoDB에 연결했습니다.

어떤 이유로 든 연결되지 않으면 오류가 발생합니다. 그렇지 않으면 FuseFussySearch라는 데이터베이스를 만듭니다.

그런 다음 person 컬렉션에 삽입하려는 모든 문서를 포함하는 personObj라는 개체를 만듭니다. 데이터를 삽입하는 동안 문제가 있으면 오류가 생성됩니다.

Fuse 객체를 생성하고 keysincludeScore가 있는 personObjoptions 객체 배열을 전달하여 위와 같이 퍼지 검색을 수행하고 결과를 얻습니다.

여기에서 keys는 검색이 수행될 필드를 지정합니다. includeScore는 선택 사항이지만 일치하는 점수를 알려주기 때문에 있는 것이 좋습니다.

0인 경우 프로그램은 완벽한 일치를 찾고 1의 점수는 완전한 불일치를 나타냅니다. 모든 옵션은 여기에서 찾을 수 있습니다.

마지막으로 연결을 닫는 것을 잊지 마십시오. 탐색할 수 있는 다른 라이브러리도 많이 있습니다.

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