Home > Blockchain >  MongoDB. Find index of element in array and count number of elements from this index
MongoDB. Find index of element in array and count number of elements from this index

Time:02-18

I have data like:

{
"_id" : ObjectId("4c02c58de500fe1be1000005"),
created_at: 2021-11-13T16:11:34.751 00:00,
"text" : "some text",
"events" : [
    {"id":"1", "status_id:"8"},
    {"id":"2", "status_id:"7"},
    {"id":"3", "status_id:"7"},
    {"id":"4", "status_id:"7"},
    {"id":"5", "status_id:"7"},
    {"id":"6", "status_id:"10"},
]
}

I need get index of first element in array events which have status_id 7 and count of elements from this index in new field and If element with status_id 7 is last in array, new field should be 0, if penultimate then new field should be 1:

For example in this case:

  {
    "_id" : ObjectId("4c02c58de500fe1be1000005"),
    created_at: 2021-11-13T16:11:34.751 00:00,
    "text" : "some text",
    "events" : [
        {"id":"1", "status_id:"1"},
        {"id":"2", "status_id:"1"},
        {"id":"3", "status_id:"1"},
        {"id":"4", "status_id:"1"},
        {"id":"5", "status_id:"7"},
        {"id":"6", "status_id:"7"},
    ]
    }

expected output should be:

{
        "_id" : ObjectId("4c02c58de500fe1be1000005"),
        created_at: 2021-11-13T16:11:34.751 00:00,
        "text" : "some text",
        "events" : [
            {"id":"1", "status_id:"1"},
            {"id":"2", "status_id:"1"},
            {"id":"3", "status_id:"1"},
            {"id":"4", "status_id:"1"},
            {"id":"5", "status_id:"7"},
            {"id":"6", "status_id:"7"},
        ],
        "new_field":2
}

I have some aggregation pipeline:

[
{'$unwind': {'path': '$events'}}, 
{'$match': {'events.created_at': {'$gt': 'created_at'}}},
{'$group': {'_id': '$id', 'events': {'$push': '$events'}, 'data': {'$first': '$$ROOT'}}}, 
]

but i don't now how i can get index according to my condition

Will be grateful for the help

CodePudding user response:

Query

  • finds the index that has statud_id="7"
  • if found(>=0) subtracks size_of_events - that_index to count the number of elements after that index
  • else returns -1 meaning not found

Test code here

aggregate(
[{"$set":
  {"new-field":
   {"$let":
    {"vars":{"index":{"$indexOfArray":["$events.status_id", "7"]}},
     "in":
     {"$cond":
      [{"$gte":["$$index", 0]},
       {"$subtract":[{"$size":"$events"}, "$$index"]}, -1]}}}}}])

CodePudding user response:

So do you just need to get how many objects there are with a status id of 7? So if it was something like

{"id":"1", "status_id:"1"},
{"id":"2", "status_id:"1"},
{"id":"3", "status_id:"7"},
{"id":"4", "status_id:"7"},
{"id":"5", "status_id:"7"},
{"id":"6", "status_id:"7"},

then would the new field be 4?

If so then use this function

function getInstances(obj)
{
    let count = 0
    for (const a in obj)
    {
      var b = obj[a]
      
      if(b.status_id == "7")
      {
        count  = 1
      }
    }
    
    return count
}

  • Related