Answers to how to find all documents until a condition met in mongodb ( 2 )

  1. 2017-10-22 02:10

    From your spartan description I can't tell how your data looks like and what information you want to retain, but for sure this is not possible with a find query. You are looking rather at an aggregation. If your data would look like this:

    /* 1 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e36"),
        "color" : "black",
        "name" : "Tim"
    }
    
    /* 2 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e38"),
        "color" : "blond",
        "name" : "Tom"
    }
    
    /* 3 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e3a"),
        "color" : "black",
        "name" : "Jack"
    }
    
    /* 4 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e3c"),
        "color" : "black",
        "name" : "Frank"
    }
    
    /* 5 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e3e"),
        "color" : "black",
        "name" : "Peter"
    }
    
    /* 6 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e40"),
        "color" : "blond",
        "name" : "Jon"
    }
    
    /* 7 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e42"),
        "color" : "black",
        "name" : "Apollo"
    }
    
    /* 8 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e44"),
        "color" : "black",
        "name" : "Zeus"
    }
    
    /* 9 */
    {
        "_id" : ObjectId("59ebda414d8a2fe38bec0e46"),
        "color" : "blond",
        "name" : "Daphne"
    }
    

    Then you could do something like this:

    db.getCollection('hair').aggregate([
    {
        $match: {
            $or: [
                {color: "black"}, 
                {color: "blond"}
            ]
        }
    }, 
    {
        $group: {
            _id: "$color", // group by color
            sum: {$sum: 1} // sum the occurrences of each color
        }
    },
    {
        $project: {
            _id: 1, 
            sum: {$sum: { $cond: [ {$and : [ { $eq: [ "$_id", "black"] },
                                                   { $gt: [ "$sum", 5] }
                                         ] },
                                         5,
                                         "$sum" ] }}
        }
    }
    ])
    

    So as I said, I don't know how your document looks like, what information you would like to keep and what not. You can also remove the $match pipeline if you would need all, but consider then the fact that no indexes are used.

  2. 2017-10-22 04:10

    Get the start/end ids and then the documents for that range. Supposing you want the consecutive persons between first and fifth person with black hair:

    var start = db.persons.find({"hair": "black"}).sort({_id:1}).limit(1).toArray()[0]._id;
    var end = db.persons.find({"hair": "black"}).sort({_id:1}).skip(4).limit(1).toArray()[0]._id;
    db.persons.find({"_id": {$gte: start, $lte: end }})
    

Leave a reply to - how to find all documents until a condition met in mongodb

◀ Go back