Search code examples
pythonmongodbpymongo

Is it possible to query the last element of an array using MongoEngine?


I'm trying to query the last element of a list in a Mongo document using MongoEngine. I can write a raw query to do this but I'm wondering if it's possible to do it without resorting to that.

So for example, while X.objects(some_list__val='Test Value') would return any objects which have some list element such that val=='Test Value', I'd like for it to only return those objects where val=='Test Value' in the final element of the list.


Solution

  • You can use $arrayElemAt or (from MongoDB 5.0 and later) $last :

    from pymongo import MongoClient
    
    db = MongoClient(port=27019)['mydatabase']
    col = db['mycollection']
    col.delete_many(({}))
    
    col.insert_many([{'record': [1, 2, 3]},
                     {'record': [2, 3, 4]},
                     {'record': [3, 4, 5]}])
    
    item_to_find = 4
    
    agg = col.aggregate([
        {'$project': {'record': '$record', 'last': {'$arrayElemAt': ["$record", -1]}}},
        {'$match': {'last': item_to_find}}
    ])
    
    print(list(agg))
    
    agg = col.aggregate([
        {'$project': {'record': '$record', 'last': {'$last': "$record"}}},
        {'$match': {'last': item_to_find}}
    ])
    
    print(list(agg))
    

    prints:

    [{'_id': ObjectId('6537065c5c20464e8749e8e5'), 'record': [2, 3, 4], 'last': 4}]
    [{'_id': ObjectId('6537065c5c20464e8749e8e5'), 'record': [2, 3, 4], 'last': 4}]
    

    https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/arrayElemAt/#mongodb-expression-exp.-arrayElemAt

    https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/last-array-element/#-last--array-operator-