How to do text search from mongodb in meteor?

In mongodb I can do this :

db.getCollection('keywords').find(
   { $text: { $search: "I have headache" } },
   { score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } )

result

{
    "_id" : "ux2dpeYKQCQRgdbzB",
    "keyword" : "Headache",
    "createdAt" : ISODate("2020-02-10T01:45:07.670Z"),
    "createdBy" : "a5oNybXwHKB8DkxdB",
    "score" : 1.33333333333333
}

and I want do that in meteor :

Keywords.find(
                { $text: { $search: keyword } },
                { score: { $meta: "textScore" }, sort: { score: { $meta: "textScore" } } }
            ).fetch()

but it get error :

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

I tried like this without sort

Keywords.find(
                { $text: { $search: keyword } },
                { score: { $meta: "textScore" } }
            ).fetch()

but I dont get score field in this document :

{
    "_id" : "ux2dpeYKQCQRgdbzB",
    "keyword" : "Headache",
    "createdAt" : ISODate("2020-02-10T01:45:07.670Z"),
    "createdBy" : "a5oNybXwHKB8DkxdB"
}

how to solve this text search in meteor and sort by score?

thanks

I would try using the raw Mongo collection with:

Keywords.rawCollection().find(

Note that this will be properly async and will only work on the server side

I do it on server side. and got error :

Keywords.rawCollection(...).find(...).fetch is not a function

I tried

Keywords.rawCollection(...).find(...)

still without score

{
    "_id" : "ux2dpeYKQCQRgdbzB",
    "keyword" : "Headache",
    "createdAt" : ISODate("2020-02-10T01:45:07.670Z"),
    "createdBy" : "a5oNybXwHKB8DkxdB"
}

I checked quickly with meteor shell in my own project and it looks like the Node driver for Mongodb
doesn’t support the simplified projection syntax anymore, so you have to provide a projection key to options:

> Promise.await(Pages.rawCollection().find({ $text: {$search: "test"} }, {projection: {score: {$meta: "textScore"}}}).toArray())
[
  {
    _id: 'RAdodezebKj6jZmsH',
    modules: [ 'AXTDHndWaLQjxsCpd' ],
    name: 'test page name',
    navbar: { enabled: true },
    createdAt: 2020-01-09T02:59:30.688Z,
    createdBy: '0',
    updatedAt: 2020-01-09T02:59:30.764Z,
    updatedBy: '0',
    score: 0.6666666666666666
  },
  {
    _id: 'ESEESN7KfuezwNKBK',
    modules: [],
    name: 'test page name',
    navbar: { enabled: true },
    createdAt: 2020-01-09T02:59:30.689Z,
    createdBy: '0',
    score: 0.6666666666666666
  }
]

Note the use of await and toArray instead of fetch because we’re talking to the raw mongodb driver, so the syntax is different.

It also seems to work with Meteor collections, but they don’t understand projection, so we use the depreciated fields key:

> Pages.find({ $text: {$search: "test"} }, {fields: {score: {$meta: "textScore"}}, sort: {score:{$meta:"textScore"}}}).fetch()
[
  {
    _id: 'RAdodezebKj6jZmsH',
    modules: [ 'AXTDHndWaLQjxsCpd' ],
    name: 'test page name',
    navbar: { enabled: true },
    createdAt: 2020-01-09T02:59:30.688Z,
    createdBy: '0',
    updatedAt: 2020-01-09T02:59:30.764Z,
    updatedBy: '0',
    score: 0.6666666666666666
  },
  {
    _id: 'ESEESN7KfuezwNKBK',
    modules: [],
    name: 'test page name',
    navbar: { enabled: true },
    createdAt: 2020-01-09T02:59:30.689Z,
    createdBy: '0',
    score: 0.6666666666666666
  }
]
2 Likes