Chris
Chris

Reputation: 14218

JS mongoDB sort by previousItem property (parent-child relationship)

I have an item collection with documents that have an order that matters and it may change (i.e. the creation time or id cannot be used for sorting).

I thought that adding a previous/nextItem properties may be a solution

{
  id: 1,
  name: "itemC",
  previousItem : 2,
  nextItem : 0
}

{
  id: 0
  name: "itemB", 
  previousItem : 1,
  nextItem : null
}

{
  id: 2,
  name: "itemA",
  previousItem : null,
  nextItem : 1
}

I would like to retrieve the records based on a sort parameter that traverses the previousItem property.

Above collection should be returned as:

{
  id: 2,
  name: "itemA",
  previousItem : null,
  nextItem : 1
}

{
  id: 1,
  name: "itemC",
  previousItem : 2,
  nextItem : 0
}

{
  id: 0
  name: "itemB", 
  previousItem : 1,
  nextItem : null
}

Upvotes: 0

Views: 41

Answers (2)

Chris
Chris

Reputation: 14218

So here are the basic assumptions for the sorting index: 1. The index property is a string in order to allow for more then 17 digits. 2. only use the last digit of the adjacent items to calculate the new index in order to avoid calculations with more than 17 digits. Algorithm (the following values are all strings):

indices:
I1
I2
I3

add item between 1 and 2 --> 
   is there an integer between the two values?
   yes --> use it as the new index
   no --> use the lower index and append 05, add 00 to lower index

eval (1,2) --> no

I100
I105
I2
I3

add an item between 100 and 105
eval(100,105) --> yes

I100
I102
I105
I2
I3

add an item between 100 and 102
eval(100,102) --> yes

I100
I101
I102
I105
I2
I3

add an item between 100 and 101
eval(100,101) --> no

I100
I1005
I101
I102
I105
I2
I3

and so on.

The output for db.getCollection('items').find({}).sort({index: 1})

produces the expected result.

Upvotes: 1

Steve Seeger
Steve Seeger

Reputation: 1477

Would adding an index to your record set and then when you query you can get your result set sorted by that index not work in your case?

https://docs.mongodb.org/v3.0/tutorial/sort-results-with-indexes/

EDIT Update:

You can use sub-division of the index, eg:

insert between elements with indexA=2 and indexB=3, generating an insertIndex = (2+3)/2 = 2.5

However, in Javascript you would need to use floats which are max 17 decimals, same as MongoDB double. You would need to account for this and if the rounding occurred, eg if insertIndex = indexA or = indexB then you hit the limitation and need to call a function to update the database and loop all elements to update their index with eg integers. After doing this the first time, it's likely it wouldn't trigger often and would trigger less and less over time.

Upvotes: 0

Related Questions