2

I have an "id" string that I'm reading from a change feed in CosmosDB. Each record is versioned, so that whenever the record is updated, the old record will be versioned to include a timestamp, and the new record will be added.

Example:

id: productbase-001.11

GETS UPDATED

id: productbase-001.11 <- new record
id: productbase-001.11-2020-03-30 <- old record

What I want to do is get the type (productbase), then get the itemId (001.11) and get the timestamp (2020-03-30). I only need the timestamp because I want to exclude the old records from my processing logic further down.

 foreach (ProcessedItem item in changes)
 {
   var convert = item.id.Split('-');
   string itemType = convert[0];
   string itemId = convert[1];
   string timestamp = convert[2];

   if (timestamp != null)
   {
       return;
   }
   else
   {
       [rest of my code]
   }
}

Obviously have a problem will null refs, and also having the "-" as a delimiter will mean that I get "2020" and "03" and "30" all as separate items in the array. Also not sure how slow this will be if I have 3000 updates coming through.

If there is a better way to get these using SQL API, then I am all ears.

secretclean
  • 55
  • 1
  • 6

2 Answers2

3

Use the String.Split overload that takes a count parameter

var convert = item.id.Split(new char[]{'-'}, 3);
string itemType = convert[0];
string itemId = convert[1];
string timestamp = (convert.Length == 3 ? convert[2] : null);

As we've specified a maximum of 3 items then the entire timestamp will be included as the last array item, if present.

Sean
  • 60,939
  • 11
  • 97
  • 136
0

There's a multiple ways that you could handle this. Here are a couple:

If you don't need the specific value of the timestamp, you could just check to see if convert has more than two items:

 foreach (ProcessedItem item in changes)
 {
     var convert = item.id.Split('-');
     string itemType = convert[0];
     string itemId = convert[1];

     if (convert.Length > 2)
     {
         return;
     }
     else
     {
         [rest of my code]
     }
 }

This is pretty non-invasive to the code that you've already written, but it wouldn't be super clear why you were doing this.

Another option would be to use a regular expression, something like:

^(?<Product>\w+)-(?<ItemNum>\d+\.\d+)-?(?<TimeStamp>\d{4}-\d{2}-\{2})?$

To me, using the named groups is very clear, but some might consider this solution to be overkill.

If it were me, I would also put all of this logic into it's own class (e.g. ProcessedItemId) or at least a static method, so that it could be reused elsewhere.

FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91