3

I created a mongodb faceted pipeline that the following is a subset of:

db.books.aggregate( [
{
    $facet: {
        "categories": [
            {
                $match: {
                    $text: { $search: "Pattern" }
                }
            }, 
            {
                $group: {
                    _id: "$Category",
                    count: {
                        $sum: 1
                    }
                }
            },
            {
                $sort: {
                    "count": -1
                }
            },
            {
                $project: {
                    "score": { "$meta": "textScore"},
                    "Category": "$_id",
                    "_id": 0,
                    "count": 1
                }
            },
            {
                $limit: 10
            }
        ]
    }
}
])

Two other output fields exist in the pipeline aside from category but resemble the structure outlined in the pipeline above. Whenever I run this pipeline I get the error: "pipeline requires text score metadata, but there is no text score available"

This error only happens when using a facet pipeline. Running each pipeline stage individually works perfectly.

The version of mongodb I'm using is 3.6.

If you have any thoughts around this, please don't hesitate to share.

0

As I have gone through your error

pipeline requires text score metadata, but there is no text score available

As per MongoDB documentation $text It performs a text search on the content of the fields indexed with a text index. A $text expression has the following syntax:

Changed in version 3.2.

{
  $text:
    {
      $search: <string>,
      $language: <string>,
      $caseSensitive: <boolean>,
      $diacriticSensitive: <boolean>
    }
}

The $text operator, by default, does not return results sorted in terms of the results’ scores. For more information on sorting by the text search scores, see the Text Score documentation.

Behavior

Restrictions

  • A query can specify, at most, one $text expression.

  • The $text query can not appear in $nor expressions.

  • The $text query can not appear in $elemMatch query expressions or $elemMatch projection expressions.
  • To use a $text query in an $or expression, all clauses in the $or array must be indexed.
  • You cannot use hint() if the query includes a $text query expression.
  • You cannot specify $natural sort order if the query includes a $text expression.
  • You cannot combine the $text expression, which requires a special text index, with a query operator that requires a different type of special index. For example you cannot combine $text expression with the $near operator.
  • Views do not support text search.

If using the $text operator in aggregation, the following restrictions also apply.

  • The $match stage that includes a $text must be the first stage in the pipeline.
  • A text operator can only occur once in the stage.
  • The text operator expression cannot appear in $or or $not expressions.
  • The text search, by default, does not return the matching documents in order of matching scores. Use the $meta aggregation expression in the $sort stage.

For example of Text Score

The $text operator assigns a score to each document that contains the search term in the indexed fields. The score represents the relevance of a document to a given text search query. The score can be part of a sort() method specification as well as part of the projection expression. The { $meta: "textScore" } expression provides information on the processing of the $text operation. See $meta projection operator for details on accessing the score for projection or sort.

The following examples assume a collection articles that has a version 3 text index on the field subject:

> db.createCollection("articles");
{ "ok" : 1 }

> db.articles.createIndex( { subject: "text" } )
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

Note:

  • MongoDB introduces a version 3 of the text index. Version 3 is the default version of text indexes created in MongoDB 3.2 and later.
  • MongoDB 2.4 introduces a version 1 of the text index. MongoDB 2.4 can only support version 1.
  • MongoDB 2.6 introduces a version 2 of the text index. Version 2 is the default version of text indexes created in MongoDB 2.6 and 3.0
    series.

Populate the collection with the following documents:

> db.articles.insert(
...    [
...      { _id: 1, subject: "coffee", author: "xyz", views: 50 },
...      { _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
...      { _id: 3, subject: "Baking a cake", author: "abc", views: 90  },
...      { _id: 4, subject: "baking", author: "xyz", views: 100 },
...      { _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
...      { _id: 6, subject: "Сырники", author: "jkl", views: 80 },
...      { _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
...      { _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
...    ]
... )
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 8,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})

Search for a Single Word

> db.articles.find( { $text: { $search: "coffee" } } )
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 }
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }

This query returns the documents that contain the term coffee in the indexed subject field, or more precisely, the stemmed version of the word.

Match Any of the Search Terms

> db.articles.find( { $text: { $search: "bake coffee cake" } } )
{ "_id" : 4, "subject" : "baking", "author" : "xyz", "views" : 100 }
{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90 }
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 }
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }

This query returns documents that contain either bake or coffee or cake in the indexed subject field, or more precisely, the stemmed version of these words.

Search for a Phrase

> db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }

To match the exact phrase as a single term, escape the quotes. This query returns documents that contain the phrase coffee shop.

Sort by Text Search Score

To sort by the text score, include the same $meta expression in both the projection document and the sort expression.

> db.articles.find(
...    { $text: { $search: "coffee" } },
...    { score: { $meta: "textScore" } }
... ).sort( { score: { $meta: "textScore" } } )
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50, "score" : 1 }
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5, "score" : 0.75 }
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10, "score" : 0.75 }

The following query searches for the term coffee and sorts the results by the descending score. The query returns the matching documents sorted by descending score.

Return Top 2 Matching Documents

Use the limit() method in conjunction with a sort() to return the top n matching documents.

> db.articles.find(
...    { $text: { $search: "coffee" } },
...    { score: { $meta: "textScore" } }
... ).sort( { score: { $meta: "textScore" } } ).limit(2)
{ "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50, "score" : 1 }
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5, "score" : 0.75 }

The following query searches for the term coffee and sorts the results by the descending score, limiting the results to the top two matching documents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.