borjagvo
borjagvo

Reputation: 2091

Get documents with unique field - Mongoid

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

Answers (1)

Blakes Seven
Blakes Seven

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

Related Questions