Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

MongoError: must have $meta projection for all $meta sort keys

I am trying to sort by $meta score the results from my $text search but every time I do I get this error message.

    MongoError: must have $meta projection for all $meta sort keys
     operationTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1584383573 },
      ok: 0,
      errmsg: 'must have $meta projection for all $meta sort keys',
      code: 2,
      codeName: 'BadValue',
      '$clusterTime': 
       { clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 2, high_: 1584383573 },
         signature: { hash: [Object], keyId: [Object] } },
      name: 'MongoError',
      [Symbol(mongoErrorContextSymbol)]: {} }

What I am trying to achieve is to allow users to search words like “ah or jo” and for my search query to find words that contain the strings passed and sort them based on relevance.

I got it to work but it wasn’t finding parts of strings BUT only whole strings… For example, If I pass “Jacob” it will find names with that string but if I pass “Jac” it will come back as null.

Here is my code

    var userData = await UserDB.userModel.find(
          {
            $or: [
              {
                $text: {$search: 'jac'}
              },
              {score : { $meta: "textScore" } } ,
                {
                  $or: [
                    {'username': {$regex: '^jac'}},
                    {'name.first': {$regex: '^jac'}},
                    {'name.last': {$regex: '^jac'}}
                  ]
                }
            ]
        }).sort( { score: { $meta: "textScore" } } )

There are two different functions and they have different purposes:

(1) Text search
(2) Regex search

(1) Text Search:

With text search you can search for words in different text fields. For example, search for “mongo” in the two text fields in a document:

{ name: "mongo database", description: "replication with mongo" }

For this you must create a text index (and this index can cover all text fields in a document). And, you can search for “mongo” or “replication”, but not “mong”, “ongo” or “repl”.

The $meta operator is used with the text searches. It can be part of the projection and the sort operation.


(2) Regex Search:

With regex search, you can search for “mong” or “ongo” or “data”.


Text Search and Stemmed Words:

For case insensitive and diacritic insensitive text searches, the $text operator matches on the complete stemmed word.

For documents:
{ name: "blueberry field" }
{ name: "blueberries" }

The following first two text searches will not match, but the last two will match:
db.collection.find( { $text: { $search: “blue” } } )
{ $text: { $search: “blueberr” } }
{ $text: { $search: “blueberry” } }
{ $text: { $search: “blueberries” } }

My question is… Is it possible to sort a regex search by relevance ? I know $text and $regex are two different functions but is there a way to combine both?