Reputation: 2091
I have a ratings
collection with the field item_id
. I need to retrieve all documents with different item_id
field. For instance, let's suppose I have this documents:
{item_id: "123", some_other_field: "bla,bla"}
{item_id: "123", some_other_field: "bla,bla"}
{item_id: "121", some_other_field: "bla,bla"}
{item_id: "120", some_other_field: "bla,bla"}
The result that I need:
{item_id: "123", some_other_field: "bla,bla"}
{item_id: "121", some_other_field: "bla,bla"}
{item_id: "120", some_other_field: "bla,bla"}
How can I achieve this? I saw this question where they propose map-reduce as the solution, but it should be something easier!
Thanks.
Upvotes: 0
Views: 431
Reputation: 50416
It's quite a lot easier if what you "mean" here is the "completely distinct" document. But what you basically need here is .aggregate()
, and specifically $group
:
Model.collection.aggregate([
{ "$group" => {
"_id" => {
"item_id" => "$item_id",
"some_other_field" => "$some_other_field"
}
}}
])
Or if you just want "distinct" on "one" field, then something like:
Model.collection.aggregate([
{ "$group" => {
"_id" => "$item_id",
"some_other_field" => { "$first" => "$some_other_field" }
}}
])
These are no longer the mongoid "documents" but you can always "cast" them back if the structure is the same, and that is possible with a little manipulation or the $project
pipeline stage.
Model.collection.aggregate([
{ "$group" => {
"_id" => "$item_id",
"some_other_field" => { "$first" => "$some_other_field" }
}},
{ "$project" => {
"_id" => 0,
"item_id" => "$_id",
"some_other_field" => "$some_other_field"
}}
])
Also to mention that this is "significantly" faster than mapReduce, as the code uses native operators to MongoDB and no JavaScript translation.
Read up on the operators for aggregation pipelines as a general guide to things you can do.
Upvotes: 2