简体   繁体   中英

Return formatted value in MongoDB db.collection.find()

I have a MongoDB JavaScript function saved in db.system.js, and I want to use it to both query and produce output data.

I'm able to query the results of the function using the $where clause like so:

db.records.find(
    {$where: "formatEmail(this.email.toString(), 'format type') == 'xxx'"},
    {email:1})

but I'm unable to use this to return a formatted value for the projected "email" field, like so:

db.records.find({}, {"formatEmail(this.email.toString(), 'format type')": 1}) 

Is there any way to do this while preserving the ability to simply use a pre-built function?

UPDATE:

Thank you all for your prompt participation.

Let me explain why I need to do this in MongoDB and it's not a matter of client logic at the wrong layer.. What I am really trying to do is use the function for a shard bucketing value. Email was just one example, but in reality, what I have is a hash function that returns a mod value.

I'm aware of Mongo having the ability to shard based on a hashed value, but from what I gather, it produces a highly random value that can burden the re-balancing of shards with unnecessary load. So I want to control it like so func(_id, mod), which would return a value from 0 to say 1000 (depending on the mod value).

Also, I guess I would also like to use the output of the function in some sort of grouping scenario, and I guess Map Reduce does come to mind.. I was just hoping to avoid writing overly complex M/R for something so simple.. also, I don't really know how to do Map Reduce .. lol.

So, I gather that from your answers, there is no way to return any formatted value back from mongo (without map/reduce), is that right?

I think you are mixing your "layers" of functionality here -- the database stores and retrieves data, thats all. What you need to do is: * get that data and store the cursor in a variable * loop through your cursor, and for every record you go through * format and output your record as you see fit. This is somewhat similar to what you have described in your question, but its not part of MongoDB and you have to provide the "formatEmail" function in your "application layer"

Hope it helps

As @alernerdev has already mentioned, this is generally not done at a database layer. However, sometimes storing a pre-formatted version in your database is the way to go. Here's some instances where you may wish to store extra data:

  • If you need to lookup data in a particular format. For example, I have a "username" and a "usernameLowercase" fields for my primary user collection. The lowercase'd one is indexed, and is the one I use for username lookup. The mixed-case one is used for displaying the username.

  • If you need to report a large amount of data in a particular format. 100,000 email addresses all formatted in a particular way? Probably best to just store them in that format in the db.

  • If your translation from one format to another is computationally expensive. Doubly so if you're processing lots of records.

In this case, if all you're doing is looking up or retrieving an email in a specific format, I'd recommend adding a field for it and then indexing it. That way you won't need to do actual document retrieval for the lookup or the display. Super fast. Disk storage space for something the size of an email address is super cheap!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM