[SERVER-5947] Add ability to project key names as values and values as key names Created: 28/May/12  Updated: 06/Dec/22  Resolved: 29/Mar/16

Status: Closed
Project: Core Server
Component/s: Aggregation Framework
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major - P3
Reporter: Asya Kamsky Assignee: Backlog - Query Team (Inactive)
Resolution: Duplicate Votes: 28
Labels: aggregation, expression, usability
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Duplicate
duplicates SERVER-18794 Add an aggregation expression to conv... Closed
duplicates SERVER-23310 Add an expression to convert an array... Closed
is duplicated by SERVER-6429 $unwind keys in a document or subdocu... Closed
Related
related to SERVER-8582 Extend document expression language i... Closed
related to SERVER-13928 Iteration over Map support Closed
is related to SERVER-11392 $unwind on subdocuments Closed
Assigned Teams:
Query
Participants:

 Description   

Aggregation framework could be a powerful way to transform one shape of document schema into another if values could be turned into keys and vice versa.

Example schema:

{ userId: "xxx", attributeName: "yyy", attributeValue: "zzz"}

could be projected into

{ userId: "xxx", "yyy": "zzz"}

for a subset of attribute names where now we can do simple $match for our criteria.

Conversely, ability to turn keys into values would allow aggregation based on existence of certain keys.
It would also allow aggregating by key rather than by value.



 Comments   
Comment by Charlie Swanson [ 29/Mar/16 ]

I'm closing this ticket, since I believe it can be accomplished by two new expressions proposed in SERVER-18794 ($objectToArray) and SERVER-23310 ($arrayToObject), and by using the existing $map. Please follow those tickets for updates.

For example, you could do

> db.foo.find()
{_id: 0, attrs: [{k: "xxx", v: "yyy"}, {k: "zzz", v: "www"}]}
> db.foo.aggregate([
  {$project: {
    newAttrs: {
      $arrayToObject: {
        $map: {
          input: "$attrs",
          as: "pair",
          in: ["$$pair.k", "$$pair.v"]
        }
      }
    }
  }}
])
{_id: 0, newAttrs: {xxx: "yyy", zzz: "www"}}

If you have a use case that you do not believe to be satisfied by these expressions, please post here and describe your use case, and we'll consider re-opening or filing a new ticket.

Comment by John A. De Goes [ 07/Nov/15 ]

These are indeed primitive operations: the ability to peek into the key names, and create new key / values dynamically.

A $keys operator could pull out the keys into an array. A $values operator could pull out the values into an array. And a corresponding $makeObject operator could create a document from an array of key / value pairs (or from two arrays). These give you the ability to solve all problems listed in this ticket.

Comment by Amit Gosavi [ 07/Oct/15 ]

Is there any activity on this JIRA? I am facing similar issue and projecting key makes sense in my scenario as well.

Comment by Billy Tetrud [ 06/Aug/14 ]

I found another case where I'd want to use this: http://stackoverflow.com/questions/11189243/unwind-an-object-in-aggregation-framework . I believe this feature would allow me to basically unwind an object by turning an object into an array then using normal unwind.

Comment by Billy Tetrud [ 25/Jul/14 ]

Yeah, I don't know the full set of default values. The values are arbitrary - user defined.

Comment by Asya Kamsky [ 25/Jul/14 ]

Actually, never mind - I was thinking you might be able to use $redact but as long as you're storing the default field you want to keep as the key rather than the value, you can't do this, unless you know the full set of possible default values.

Comment by Asya Kamsky [ 25/Jul/14 ]

You may not need new functionality to be able to do what you ask for, as long as you know in advance all possible values of "default" - do you?

Comment by Billy Tetrud [ 25/Jul/14 ]

I'd also like to see this. Here's my use case: http://stackoverflow.com/questions/24950215

Comment by David Murphy [ 09/Oct/13 ]

I think the perfect use case is system.profiler, where you cant use mapReduce but you might need to pull off something like:

 
{
	op: "i",
	count: <count of times run>,
	queryPattern: [field1,field2,field3],
	total_examined:<int>,
	total_returned:<int>,
	return_ratio:<float>
},
{
	op: "u",
	count: <count of times run>,
	queryPattern: [field2,field4,field8],
	total_examined:<int>,
	total_returned:<int>,
	return_ratio:<float>
}

As a summary of query's run similar to pt-query-digest or mysqlsla

Comment by Asya Kamsky [ 02/Feb/13 ]

Encountered another use case:
Schema:

 
{ _id: <id>,
  field1: 5
},
{ _id: <id>,
  field2: 9
}
 

If you need to sort by fieldN across differently named fields, or get a sum of values stored in more than one field in a single query, it would be simpler if this feature was available.

Generated at Thu Feb 08 03:10:20 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.