Mongoose with search autocomplete index - mongodb

I want an autocomplete search on a name field in my collection on MongoDB Atlas. I've configured a search index in MongoDB atlas as following:
{
"mappings": {
"dynamic": false,
"fields": {
"name": {
"foldDiacritics": false,
"maxGrams": 8,
"type": "autocomplete"
}
}
}
}
and I'm trying to search via mongoose a substring in the entire collection like this:
collection.aggregate([
{
$search: {
autocomplete: {
path: 'name',
query: query,
},
},
},
{
$limit: 10,
},
{
$project: {
_id: 0,
name: 1,
},
},
]);
I always get 0 results, does anyone can help me understand what am I doing wrong?
Thanks,
Erez

The problem was that I've changed the default index name (which is 'default') and in that case, I needed to specify the new index name in the query or change the index to be named 'default'. Didn't found any mention of that in the MongoDB documentation though.

Related

MongoDB Autocomplete give priority to certain records based on attribute

I am using the atlas search autocomplete feature for a collection of Songs in MongoDb.
If I query the song "Santa Claus Is Comin' To Town" using autocomplete, I get back many versions of this song by many different artists.
A Song in my case has a "popular": true attribute, if the song is a popular version of the song.
I am looking to prioritize documents that have "popular": true so that they are returned first in the autocomplete result list. The way I currently have this search configured does not pay attention to this popular attribute. How might I boost these popular records?
Here is the index that I defined in Atlas Search:
{
"mappings": {
"dynamic": false,
"fields": {
"name": [
{
"foldDiacritics": false,
"maxGrams": 7,
"minGrams": 3,
"tokenization": "edgeGram",
"type": "autocomplete"
}
]
}
}
}
And here is the query I am using to fetch the results:
let results = await Song.aggregate([
{
$search: {
index: "asset_autocomplete",
autocomplete: {
query: req.query.name,
path: "name",
tokenOrder: "sequential",
},
},
},
{
$project: {
name: 1,
_id: 1,
},
},
{
$limit: 10,
},
]);

Atlas autocomplete in array

I am trying to create a search index on atlas for a field in an object in an array.
However, the index I created doesn't work.
Example of the data:
{
"_id": "zyicGj7d2R3ezKB6s",
"arrayData": [{
_id: 'roGxCLhJPhQ7NLNed',
name: 'test'
},
{
_id: 'ziPszDHvSYXroLuFm',
name: 'test2'
}
],
}
The index I have at the moment is
{
"mappings": {
"dynamic": false,
"fields": {
"arrayData.name": {
"tokenization": "nGram",
"type": "autocomplete"
}
}
}
}
For the search I need it to be type autocomplete and I want to search on the name in the object's

Mongodb Atlas Search Autocomplete is slow on sort with large data set

I have used an atlas search for finding Hashtags. I would like to sorting on t_status and count fields. t_status field does not exist in most of documents but it has exist in some documents.
Hashtags save in _id field.
search autocomplete index :
{
"mappings": {
"dynamic": false,
"fields": {
"_id": {
"foldDiacritics": false,
"maxGrams": 10,
"minGrams": 1,
"tokenization": "edgeGram",
"type": "autocomplete"
}
}
}
}
Search aggregate query :
[
{
'$search': {
'index': 'default',
'autocomplete': {
'query': 'a',
'path': '_id'
}
}
}, {
'$sort': {
't_status': -1,
'count': -1
}
}, {
'$limit': 20
}
]
Above search query slow on sorting with huge data set.
Anyone can Give me the solution of this question?

use geonear with fuzzy search text mongodb

I have the following query
db.hotels.aggregate([
{
$search: {
index:'txtIdx', // this is the index name
text: {
query:"sun",
path:['name','address.landmark','address.city','address.state','address.country'],
fuzzy: {
maxEdits:2,
prefixLength: 1,
},
},
},
},
{
$project: {
_id: 1,
name: 1,
address:1,
score: { $meta: "searchScore" }
}
},
{$limit:100},
])
there is also a field called 'location' in hotels' collection, which has coordinates as follows
"location": {
"type": "Point",
"coordinates": [
72.867804,
19.076033
]
}
how can I use geonear with this search query to only return near by hotels from user, with provided latitude, longitude and distance.
I also tried this query
{
$search: {
index:'searchIndex',
compound: {
must: {
text: {
query:'sun',
path:['name','address.landmark','address.city','address.state','address.country'],
fuzzy: {
maxEdits:2,
prefixLength: 3,
},
},
},
should: {
near:{
origin: {
type: 'Point',
coordinates: [-122.45665489904827,37.75118012951178],
},
pivot: 1000,
path: 'location'
},
}
}
}
},
but above query returns results which are not even around that location. It returns same result as 'search' would provide without 'near'.I have created 'geo' index for location, still it doesn't return nearby hotels.
Or is there another way apart from using geonear along with search? I am trying since past 2 days now, and I haven't found anything useful. Also I want to use fuzzy text search only. Please let me know if there is a way to solve this?

How to apply a filter, before running MongoDB Atlas full text search?

According to the documentation about Atlas Search, it states:
$search must be the first stage of any pipeline it appears in.
Well if that is the case, how do you apply Mongo filters.
It seems very counter-intuitive to apply these filters on the output of the search?
We are thinking about using Mongodb full text search as an alternative to Algolia, but this limitation seems weird 🧐
Current pipeline:
const pipeline = [
{
$search: {
text: {
query,
path: fields,
fuzzy: {
maxEdits: 1,
maxExpansions: 50,
},
},
},
},
{
$match: {
someField: 1,
},
},
];
In this case, it may be better to index someField in Atlas Search as a number, as it supports numeric types using the range operator and compound to combine the results. Since the entire query is run in Lucene, it should return results quicker.
const pipeline = [
{
$search: {
compound: {
should: {
text: {
query,
path: fields,
fuzzy: {
maxEdits: 1,
maxExpansions: 50,
},
},
},
filter: {
range: {
path: "someField",
lte: 1,
gte: 1
}
}
}
}
}
];