sql >> Database >  >> NoSQL >> MongoDB

Hoe gaat MongoDB om met de documentlengte in een tekstindex en tekstscore?

Scoren is gebaseerd op het aantal gestemde overeenkomsten, maar er is ook een ingebouwde coëfficiënt die de score voor overeenkomsten aanpast ten opzichte van de totale veldlengte (waarbij stopwoorden zijn verwijderd). Als uw langere tekst meer relevante woorden voor een zoekopdracht bevat, zal dit bijdragen aan de score. Langere tekst die niet overeenkomt met een zoekopdracht, verlaagt de score.

Fragment van MongoDB 3.2 broncode op GitHub (src/mongo/db/fts/fts_spec.cpp ):

   for (ScoreHelperMap::const_iterator i = terms.begin(); i != terms.end(); ++i) {
        const string& term = i->first;
        const ScoreHelperStruct& data = i->second;

        // in order to adjust weights as a function of term count as it
        // relates to total field length. ie. is this the only word or
        // a frequently occuring term? or does it only show up once in
        // a long block of text?

        double coeff = (0.5 * data.count / numTokens) + 0.5;

        // if term is identical to the raw form of the
        // field (untokenized) give it a small boost.
        double adjustment = 1;
        if (raw.size() == term.length() && raw.equalCaseInsensitive(term))
            adjustment += 0.1;

        double& score = (*docScores)[term];
        score += (weight * data.freq * coeff * adjustment);
        verify(score <= MAX_WEIGHT);
    }
}

Een aantal testgegevens instellen om het effect van de lengtecoëfficiënt op een heel eenvoudig voorbeeld te zien:

db.articles.insert([
    { headline: "Rock" },
    { headline: "Rocks" },
    { headline: "Rock paper" },
    { headline: "Rock paper scissors" },
])

db.articles.createIndex({ "headline": "text"})

db.articles.find(
    { $text: { $search: "rock" }},
    { _id:0, headline:1, score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" }})

Geannoteerde resultaten:

// Exact match of raw term to indexed field
// Coefficent is 1, plus 0.1 bonus for identical match of raw term
{
  "headline": "Rock",
  "score": 1.1
}

// Match of stemmed term to indexed field ("rocks" stems to "rock")
// Coefficent is 1
{
  "headline": "Rocks",
  "score": 1
}

// Two terms, one matching
// Coefficient is 0.75: (0.5 * 1 match / 2 terms) + 0.5
{
  "headline": "Rock paper",
  "score": 0.75
}

// Three terms, one matching
// Coefficient is 0.66: (0.5 * 1 match / 3 terms) + 0.5
{
  "headline": "Rock paper scissors",
  "score": 0.6666666666666666
}


  1. MongoDB best practice voor verwijzingen

  2. MongoDB Vind Exact Array Match, maar de volgorde doet er niet toe

  3. waarom het gebruik van een ORM met NoSql (zoals MongoDB)

  4. Wat zijn de belangrijkste verschillen tussen Redis Pub/Sub en Redis Stream?