Text index required for $text query

I want to seach an item in db by text and implement this in pipeline (because I need to join tables).
My function is

Moralis.Cloud.define("test", async (request) => {
  const query = new Moralis.Query("itemCreatedData");
  const pipeline = [ 
  	{ match: { $text: { $search: "queen" } } }
  ]
  const response = await query.aggregate(pipeline);
  return response
})

But I get an error

{
  "code": 141,
  "error": "text index required for $text query"
}

Does the $text works in moralis mongoDB or the only option I have is to use query.fullText

There is another option to search a substring, directly without pipeline. I think that it is with march

query.matches

There is the option only without pipeline?
This is not I’d like, since I need in pipeline lookup to join two tables.
I want that my function finds the most relevant object by text and then it joins with another table.

I don’t know of an option with pipeline, it may be there an option too.
the syntax should be specific to mongo db

Okay, then maybe someone else could help because I don’t understand.
I use $text for searching by text in db how it’s said in documentation https://www.mongodb.com/docs/v3.2/text-search/ .
But it just throws an error "error": "text index required for $text query"

Have you created a text index? Text Indexes — MongoDB Manual

Oh, No I don’t. How can I create a text index in moralis table?
In documentation I found that I can do it only when I work in node.js

You’ll have to do it when connecting to your MongoDB instance directly.

Syntax according to the docs should be:

const table = client.db('admin').collection('itemCreatedData');
const result = await table.createIndex({ fieldhere: 'text' });
console.log(result);

Excuse me, but to connect to MongoDB I have to provide in client MONGO_HOST and MONGO_PORT
but I see only IP for MONGO_HOST. Where is MONGO_PORT

The port is after the :. E.g. ipaddress:12345, the port is 12345.

Okay, I’m now on a half way but now I can’t get data. Before createIndex and wanted to check if everything works and for that I just asked get all data in table

const MONGO_HOST = "xxx"
const MONGO_PORT = "xxx"

const uri = `mongodb://${MONGO_HOST}:${MONGO_PORT}`
const client = new MongoClient(uri)

await client.connect()
const database = client.db("admin")

const collection = database.collection("itemCreatedData")
const data = await collection.find({}).toArray() //  = []

My code works but I just get empty data. Maybe it’s a problem with permissions but I checked and read is enabled

try with parse as db there instead of admin

Finally it works correctly. Ty everyone for help!!

1 Like

can you share your solution, what index did you add?

await client.connect()

const database = client.db("parse")
const collection = database.collection("itemCreatedData")

await collection.createIndex({ title: "text" })

const datas = await collection.aggregate([{ $match: { $text: { $search: "queen" } } }]).toArray()
1 Like

You can also achieve it by writing a regex like this.
PS: The example below is meant to check if the username starts with request.params.username

const pipeline = [
        {
            match: {
                username: { $regex: `^${request.params.username}` },
            },
        }
]
1 Like

Hm, ye, your implementation is much simpler than mine.
But it has drawback that it doesn’t ignore case sensitive. Maybe it can through /i/ but I can’t seem to do it

Regex worked decently for me. Index caused pain. Interested to see how well it holds up with large data sets.

Out of curiosity, what’s the best way to $or the regex searches for multiple fields. I tried match: $or: [] and it didn’t like it. :thinking:

UPDATE:
Never mind, got it. It didn’t like string interpolation for my regex+options, so I just used $options for the options.