简体   繁体   中英

MongoDB/JS: How to get all unique string values of array field

I need to get all unique values of the arrays of each selected document from mongoDB (using meteorJS and this has to be done on server side).

datastructure

{ 
  _id: 'Wt7gSvxSPbRw46KHK',
  parent: 'doxCi4MSNmFJE43EH',
  target: [ 'ejiSooMx6czQxzWmW', 'Q297RZEYKJdWWRyTJ' ] 
}

This is my query and target is an array with string elements.

query

Collection.find(
  { parent: parent, target: { $exists: true } },
  { field: { target: 1 } }
).map(doc => { return doc.target })

Right now my result of this query would look like this:

[ 
  [ 'Q297RZEYKJdWWRyTJ' ],
  [ 'Q297RZEYKJdWWRyTJ', 'ejiSooMx6czQxzWmW' ],
  [ 'ejiSooMx6czQxzWmW', 'Q297RZEYKJdWWRyTJ' ],
  [ 'ejiSooMx6czQxzWmW' ] 
]

The first problem for me is to map the content of the arrays not the arrays itself, which should look like this:

[ 
  'Q297RZEYKJdWWRyTJ',
  'Q297RZEYKJdWWRyTJ', 'ejiSooMx6czQxzWmW',
  'ejiSooMx6czQxzWmW', 'Q297RZEYKJdWWRyTJ',
  'ejiSooMx6czQxzWmW' 
]

And at least the result should have unique values:

[ 'Q297RZEYKJdWWRyTJ', 'ejiSooMx6czQxzWmW' ]

You can use filter for getting unique array elements

var unique = array.filter(function(value, index, self) { 
    return self.indexOf(value) === index;
});

You can use .concat() and .apply() and .reduce() :

var uniqArray = [].concat.apply([],
  Collection.find(
    { parent: parent, target: { $exists: true } },
    { field: { target: 1 } }
  ).map(doc => doc.target )
).reduce((acc,curr) => (acc.indexOf(curr) === -1) ? acc.concat(curr) : acc,[])

Returns this:

[
    "Q297RZEYKJdWWRyTJ",
    "ejiSooMx6czQxzWmW"
]

Which is what you are asking for.

Alternately you should be able to use .rawCollection() and .distinct()

var uniqArray = Collection.rawCollection().distinct("target",{
  parent: parent, target: { "$exists": true }
})

You can use underscore.js to solve this cleanly, and it is already included in meteor

_.chain( Collection.find({ parent: parent, target: { $exists: true } }).fetch() )
 .pluck('target')
 .flatten()
 .value();

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