복붙노트

[MONGODB] MongoDB의 전체 및 부분 텍스트 검색

MONGODB

MongoDB의 전체 및 부분 텍스트 검색

약 :

수집:

색인 생성을 텍스트 :

  BasicDBObject keys = new BasicDBObject();
  keys.put("name","text");

  BasicDBObject options = new BasicDBObject();
  options.put("name", "userTextSearch");
  options.put("unique", Boolean.FALSE);
  options.put("background", Boolean.TRUE);

  userCollection.createIndex(keys, options); // using MongoTemplate

문서:

쿼리 :

내가 쿼리로 "LEO"또는 "L"을 사용하여 0 결과를 얻을 왜 어떤 생각?

텍스트 인덱스 검색을 정규식은 허용되지 않습니다.

db.getCollection('users')
     .find( { "$text" : { "$search" : "/LEO/i", 
                          "$caseSensitive": false, 
                          "$diacriticSensitive": false }} )
     .count() // 0 results

db.getCollection('users')
     .find( { "$text" : { "$search" : "LEO", 
                          "$caseSensitive": false, 
                          "$diacriticSensitive": false }} )
.count() // 0 results

MongoDB를 문서 :

해결법

  1. ==============================

    1.MongoDB를 3.4에 따라, 텍스트 검색 기능은 중지 단어 및 형태소 분석을 위해 언어 별 규칙에 텍스트 내용에 대소 문자를 구분 검색을 지원하도록 설계되었습니다. 지원되는 언어에 대한 형태소 분석 규칙은 일반적으로 일반 동사와 명사를 처리하지만, 고유 명사인지하지 못하는 표준 알고리즘을 기반으로합니다.

    MongoDB를 3.4에 따라, 텍스트 검색 기능은 중지 단어 및 형태소 분석을 위해 언어 별 규칙에 텍스트 내용에 대소 문자를 구분 검색을 지원하도록 설계되었습니다. 지원되는 언어에 대한 형태소 분석 규칙은 일반적으로 일반 동사와 명사를 처리하지만, 고유 명사인지하지 못하는 표준 알고리즘을 기반으로합니다.

    이 부분 또는 퍼지 일치에 대한 명시 적 지원은 없지만, 비슷한 결과로 줄기 용어는 다음과 같은 작동하는 것처럼 보일 수 있습니다. . 예를 들어 : "맛", "맛"과 세련된 "TAST"모든 줄기 "눈 뭉치가 더 많은 단어와 형태소 분석 알고리즘 실험 데모 페이지를 형태소보십시오.

    일치하는 결과가 같은 단어 "레오 넬 '에 대한 모든 변형이며, 케이스와 발음 구별 만 다릅니다. "레오 넬은"선택한 언어의 규칙에 의해 짧은 뭔가 막아야 할 수 있습니다하지 않는 한, 이러한 일치 변화의 유일한 유형입니다.

    당신이 효율적인 부분 일치를하고 싶은 경우에 당신은 다른 접근을해야합니다. 유용한 아이디어를 참조 :

    SERVER-15090 : 일부 단어 일치를 지원하기 위해 텍스트 인덱스를 개선하면 MongoDB의 문제 추적기에 upvote에 / 볼 수있는 관련 개선 요구가있다.

  2. ==============================

    2.로 몽고는 현재 없습니다 기본적으로 부분 검색을 지원합니다 않습니다 ...

    로 몽고는 현재 없습니다 기본적으로 부분 검색을 지원합니다 않습니다 ...

    나는 간단한 정적 방법을 만들었습니다.

    import mongoose from 'mongoose'
    
    const PostSchema = new mongoose.Schema({
        title: { type: String, default: '', trim: true },
        body: { type: String, default: '', trim: true },
    });
    
    PostSchema.index({ title: "text", body: "text",},
        { weights: { title: 5, body: 3, } })
    
    PostSchema.statics = {
        searchPartial: function(q, callback) {
            return this.find({
                $or: [
                    { "title": new RegExp(q, "gi") },
                    { "body": new RegExp(q, "gi") },
                ]
            }, callback);
        },
    
        searchFull: function (q, callback) {
            return this.find({
                $text: { $search: q, $caseSensitive: false }
            }, callback)
        },
    
        search: function(q, callback) {
            this.searchFull(q, (err, data) => {
                if (err) return callback(err, data);
                if (!err && data.length) return callback(err, data);
                if (!err && data.length === 0) return this.searchPartial(q, callback);
            });
        },
    }
    
    export default mongoose.models.Post || mongoose.model('Post', PostSchema)
    

    사용하는 방법:

    import Post from '../models/post'
    
    Post.search('Firs', function(err, data) {
       console.log(data);
    })
    
  3. ==============================

    3.인덱스를 생성하지 않고, 우리는 간단하게 사용할 수 있습니다 :

    인덱스를 생성하지 않고, 우리는 간단하게 사용할 수 있습니다 :

    db.users.find ({이름 / / I}) (케이스 둔감)

  4. ==============================

    4.나는 NPM에 여기 몽구스 플러그인에서 @Ricardo Canelas '대답을 포장

    나는 NPM에 여기 몽구스 플러그인에서 @Ricardo Canelas '대답을 포장

    두 변경했다 : - 용도의 약속 - String 형과 모든 필드에서 검색

    여기에서 중요한 소스 코드는 다음과 같습니다

    // mongoose-partial-full-search
    
    module.exports = exports = function addPartialFullSearch(schema, options) {
      schema.statics = {
        ...schema.statics,
        makePartialSearchQueries: function (q) {
          if (!q) return {};
          const $or = Object.entries(this.schema.paths).reduce((queries, [path, val]) => {
            val.instance == "String" &&
              queries.push({
                [path]: new RegExp(q, "gi")
              });
            return queries;
          }, []);
          return { $or }
        },
        searchPartial: function (q, opts) {
          return this.find(this.makePartialSearchQueries(q), opts);
        },
    
        searchFull: function (q, opts) {
          return this.find({
            $text: {
              $search: q
            }
          }, opts);
        },
    
        search: function (q, opts) {
          return this.searchFull(q, opts).then(data => {
            return data.length ? data : this.searchPartial(q, opts);
          });
        }
      }
    }
    
    exports.version = require('../package').version;
    
    // PostSchema.js
    import addPartialFullSearch from 'mongoose-partial-full-search';
    PostSchema.plugin(addPartialFullSearch);
    
    // some other file.js
    import Post from '../wherever/models/post'
    
    Post.search('Firs').then(data => console.log(data);)
    
  5. ==============================

    5.

    import re
    
    db.collection.find({"$or": [{"your field name": re.compile(text, re.IGNORECASE)},{"your field name": re.compile(text, re.IGNORECASE)}]})
    
  6. from https://stackoverflow.com/questions/44833817/mongodb-full-and-partial-text-search by cc-by-sa and MIT license