How can I include arrays of integers in my compound search?

I am working on a function that helps me find similar documents, sorted by score, using the full-text search feature of MongoDB Atlas.

I set my collection index as “dynamic”.

I am looking for similarities in text fields, such as “name” or “description”, but I also want to look in another field, “thematic”, that stores integer values (ids) of thematics.


Example:

Let say that I have a reference document as follows:

{
 name: "test",
 description: "It's a glorious day!",
 thematic: [9, 3, 2, 33]
}

I want my search to match these int in the thematic field and include their weight in the score calculation.

For instance, if I compare my reference document with :

{
 name: "test2",
 description: "It's a glorious night!",
 thematic: [9, 3, 6, 22]
}

I want to increase the score since the thematic field shares the 9 and 3 values with the reference document.


Question:

What search operator should I use to achieve this? I can input array of strings as queries with a text operator but I don’t know how to proceed with integers.

Should I go for another approach? Like splitting the array to compare into several compound.should.term queries?

Note that I also posted this question on SO here: How can I search in arrays of integers with a compound MongoDB Atlas search query? - Stack Overflow

1 Like

Than problem than you ! I want to search int in array :slight_smile:

I hope new feature soon or any solution !

I solved it by adding a trigger to my collection. Each time a document is inserted or updated, I update the thematic and other fields counterpart, e.g. _thematic, where I store the string value of the integers. I then use this _thematic field for search.

Another way to solve this is to make a custom analyser with character mapping that will replace each digit with its string counterpart. I haven’t tried this one tho.

Can you show me an example ? Thanks

Here you go (trigger code):

exports = function (changeEvent) {

const fullDocument = changeEvent.fullDocument;
const format = (itemSet) => {
    let rst = [];
    Object.keys(itemSet).forEach(item => rst.push(itemSet[item].toString()));
    return rst;
};
let setter = {      
    _thematic: fullDocument.thematic ? format(fullDocument.thematic) : [],      
};
const docId = changeEvent.documentKey._id;

const collection = context.services.get("my-cluster).db("dev").collection("projects");

const doc = collection.findOneAndUpdate({ _id: docId },
    { $set: setter });

return;
};

I am not sure it is the right way to write this kind of trigger, but it works. Alternatives or advice on how to improve this are welcome

1 Like