How can we use $filter in combination with $expr in find() function

Hi,

I have a collection with documents containing an array as below. I would like to remove the specific array objects from the “changes” array, based on the value of “updatedTimestamp” (older than 2 years) from this collection and place it in another collection.

I am able to project based on requirement using aggregation but this should be done using find() as there is a restriction for this use case. The restriction is Online Archive does not allow aggregation pipeline and it accepts custom criteria in the form of a JSON which has to be as db.collection.find({}).

Query I have is

db.temp.aggregate([
{ $match: { "changes": {$exists:true} } },
{ $project: {
    "changes": {
        $filter: { input: "$changes", as:"changes", cond: { $lt: [ "$$changes.updatedTimestamp", NumberLong(ISODate().getTime() - 63072000000) ] } } //for 2 years
        },
    }
}])

Document Structure

 "changes" : [ 
        {
            "type" : "NEW",
            "newValue" : "123",
            "oldValue" : "",
            "updatedBy" : "System",
            "field" : "logKey",
            "updatedTimestamp" : NumberLong(1536734184000)
        }, 
        {
            "type" : "NEW",
            "newValue" : "234",
            "oldValue" : "",
            "updatedBy" : "System",
            "field" : "releaseKey",
            "updatedTimestamp" : NumberLong(1674818289272)
        }
    ]

Could you please let me know if there are any feasible options.

Hi @Satyanarayana_Ettamsetty1 - Welcome to the community :wave:

Based on the above, my interpretation is that you wish to move the contents (or specific element which matches the $filter conditions in the changes array field) to another collection and have these archived using Online Archive - Is this correct? - i.e., You only want the elements filtered archived rather than the updated document.

If the above is somewhat correct I believe you’re only wanting to archive the following then?:

{
        type: 'NEW',
        newValue: '234',
        oldValue: '',
        updatedBy: 'System',
        field: 'releaseKey',
        updatedTimestamp: Long("1674818289272")
}

To better clarify could you provide the following information:

  • What documents you are trying to archive
  • The purpose of the second collection mentioned when you advise “another collection” - Is this the online archive collection?

Regards,
Jason

2 Likes

Yes. The requirement is to archive an element alone from that array. Correct, The collection that I am referring to is Online Archive collection.

Thanks for clarifying Satyanarayana.

Array properties are currently not supported in partition fields for Online Archive. You can raise a feedback post, which the product team monitor, with your use case details in which others can vote for.

Regards,
Jason