Description

I am porting a network-oriented application from PostgreSQL to MongoDB. The application makes heavy use of the 'inet' and 'mac' data types, especially when searching for IP addresses in a netblock.

One could argue that IP Addresses can simply be stored and searched as strings, which is true. However, it becomes increasingly difficult when you throw in netmasks and IPv6. For example, the IPv6 address "FFAB::1234" is really "FFAB:0000:0000:0000:0000:0000:0000:1234", and both forms are acceptable string representations.

I could not find any plans for including this feature in MongoDB, so I decided to tackle it myself. The resulting work can be found at:

The application I'm porting also makes heavy use of UUIDs, so I've modified the Shell UUID type so it is now a native type of JavaScript. This now works (no need to say 'new UUID(...'
var uuid = UUID("123456789abcdef12345678901234567");
db.test.insert(

{uuid: UUID("123456789abcdef12345678901234567")}

)

The branch listed above includes the code changes against the latest master (as of 24 Jan 2011), plus unit tests in both dbtests/ and jstests/.

The lack of support for native IP and MAC addresses has prevented me from using MongoDB. Any possibility of the main branch picking up the code? I'd be willing to port these features from 1.8 to the latest branch.

Daris A Nevil
added a comment - Sep 05 2012 10:49:57 PM +00:00 The lack of support for native IP and MAC addresses has prevented me from using MongoDB. Any possibility of the main branch picking up the code? I'd be willing to port these features from 1.8 to the latest branch.

I haven't touched mongodb since the 1.4->1.6 upgrade (which runs in an isolated environment happily since then , but for a new project, I started to re-evaluate possible solutions and I sadly discovered that mongodb still doesn't have native IP address support.
This is a must everywhere where the task is not only to store and search a single IP address, but handle subnetting, or IPv6.

Nagy, Attila
added a comment - Feb 10 2014 07:30:10 PM +00:00 I haven't touched mongodb since the 1.4->1.6 upgrade (which runs in an isolated environment happily since then , but for a new project, I started to re-evaluate possible solutions and I sadly discovered that mongodb still doesn't have native IP address support.
This is a must everywhere where the task is not only to store and search a single IP address, but handle subnetting, or IPv6.

Have you considered, at least in the short term, storing the data as a 64bit integer and writing your own serializer/deserializer to convert? I'm not sure which language you're writing in, but this seems like it would get you at least a portion of what you want. I wish the bsonspec supported unsigned integers so we could use a 32bit, but 64 works well enough. When you want to search for all IPs in a range in your app, you just calculate the start and finish integer equiv of the IP. Given that an ipv4 address is just a 32bit object, any data type that supports range queries (gt, lt, etc) would work just fine. You could even use hex strings if you were so inclined. Though, I would wager that an int would search faster because of its fixed scope [vs text, etc]

Chad Kreimendahl
added a comment - Feb 10 2014 07:45:59 PM +00:00 Have you considered, at least in the short term, storing the data as a 64bit integer and writing your own serializer/deserializer to convert? I'm not sure which language you're writing in, but this seems like it would get you at least a portion of what you want. I wish the bsonspec supported unsigned integers so we could use a 32bit, but 64 works well enough. When you want to search for all IPs in a range in your app, you just calculate the start and finish integer equiv of the IP. Given that an ipv4 address is just a 32bit object, any data type that supports range queries (gt, lt, etc) would work just fine. You could even use hex strings if you were so inclined. Though, I would wager that an int would search faster because of its fixed scope [vs text, etc]

Sure, but it quickly starts getting ugly.
Like when I'd like to store CIDR format addresses and want to check whether a given address (/32 or /128), or a subnet is in any of them.
Yes, it can be solved by math (of course, that's the same the DB does with supporting these kind of addresses), but it's so hackish.

Nagy, Attila
added a comment - Feb 10 2014 08:05:27 PM +00:00 Sure, but it quickly starts getting ugly.
Like when I'd like to store CIDR format addresses and want to check whether a given address (/32 or /128), or a subnet is in any of them.
Yes, it can be solved by math (of course, that's the same the DB does with supporting these kind of addresses), but it's so hackish.

I think mongo could add support for IP Address searching, ranges, etc, without having to change BSON to add it as a feature. Addresses themselves are just a set of bytes. They could use standard binary storage and do searching based on bit masking (which would actually index incredibly well). You could also, in theory do some CIDR type searches. Really, you're talking about wiring up something to interpret the string forms of an IP into binary, and then wiring up something to allow you to search those.

CIDR search: db.Collection.find({IPAddress;

{ $in: Network('192.168.0.0/16') }

});

Then when entering the data, you'd just need something to convert it to binary properly... but that could be done in drivers.

Chad Kreimendahl
added a comment - Jan 29 2016 07:16:52 PM +00:00 I think mongo could add support for IP Address searching, ranges, etc, without having to change BSON to add it as a feature. Addresses themselves are just a set of bytes. They could use standard binary storage and do searching based on bit masking (which would actually index incredibly well). You could also, in theory do some CIDR type searches. Really, you're talking about wiring up something to interpret the string forms of an IP into binary, and then wiring up something to allow you to search those.
CIDR search: db.Collection.find({IPAddress;
{ $in: Network('192.168.0.0/16') }
});
Then when entering the data, you'd just need something to convert it to binary properly... but that could be done in drivers.