engrhussainahmad
engrhussainahmad

Reputation: 1134

Fetch MongoDB collection records with multiple conditions

I want to fetch mongodb collection with multiple conditions but I am getting the error:

panic: Failed to parse: filter: [ { visibility: { $eq: "4" } }, { 
discontinued: { $ne: "1" } }, { status: { $eq: "1" } } ]. 'filter' field 
must be of BSON type Object.

The code is as follow:

package main

import (
    "fmt"
    "gopkg.in/mgo.v2/bson"
)

func GenerateFeed(headers, attributes interface{}, conditions 
[]interface{}) {
    var operations = []bson.M{}

    for _, val := range conditions {
        var attr, operator, value interface{}
        cons := val.(map[interface{}]interface{})
        for range cons {
            attr     = cons["attribute"]
            operator = cons["operator"]
            value    = cons["value"]

            switch operator {
                case "==":
                    operator = "$eq"
                case "!=":
                    operator = "$ne"
                case "()":
                    operator = "$in"
            }
        }
        operations = append(operations, bson.M{attr.(string): 
        bson.M{operator.(string): value}})
    }

    var products []Prod

    session := Connect()
    collection := session.DB("rfgv2").C("catalog_product_entity_1")
    err := collection.Find(operations).All(&products)
    CheckError(err)

    fmt.Println(products)
}

type Prod struct {
    EntityId                string  `bson:"entity_id"`
    Name                    string  `bson:"name"`
    TypeId                  string  `bson:"type_id"`
    Sku                     string  `bson:"sku"`
    Manufacturer            int32   `bson:"manufacturer"`
    Status                  int32   `bson:"status"`
    Visibility              int32   `bson:"visibility"`
    EnableGoogleCheckout    int32   `bson:"enable_google_checkout"`
    Delivery                string  `bson:"delivery"`
    MetaTitle               string  `bson:"meta_title"`
    MetaDescription         string  `bson:"meta_description"`
    Image                   string  `bson:"image"`
    SmallImage              string  `bson:"small_image"`
    Thumbnail               string  `bson:"thumbnail"`
    Gallery                 string  `bson:"gallery"`
    UrlKey                  string  `bson:"url_key"`
    UrlPath                 string  `bson:"url_path"`
    Mpn                     string  `bson:"mpn"`
    ProductListingAds       string  `bson:"product_listing_ads"`
    Color                   string  `bson:"color"`
    Price                   float32 `bson:"price"`
    Cost                    float32 `bson:"cost"`
    TierPriceForBundle      float32 `bson:"tier_price_for_bundle"`
    RegularPrice            float32 `bson:"regular_price"`
    SpecialFromDate         string  `bson:"special_from_date"`
    Description             string  `bson:"description"`
    MetaKeyword             string  `bson:"meta_keyword"`
    Dimensions              string  `bson:"dimensions"`
    Features                string  `bson:"features"`
    DeliveryPopupMessage    string  `bson:"delivery_popup_message"`
    CreatedAt               string  `bson:"created_at"`
    UpdatedAt               string  `bson:"updated_at"`
}

I am trying to fetch records based on multiple aggregate functions from mongodb with go. Basically if we remove the square brackets and try with mongo command it works, but how to fix this in go?

Thank You.

Upvotes: 0

Views: 346

Answers (1)

charly3pins
charly3pins

Reputation: 388

The problem vas you were declaring the operationsas a []bson.M{}, so you're obtaining an array of maps.

If you check the definition of bson.M{} it's a map[string]interface{} You just need to add elements to the map (in your case the operations you want). For do this, the syntax is yourMap[yourKey] = yourValue.

Try the following code for the operations loop generation:

operations := bson.M{}
for _, val := range conditions {
    var attr, operator, value interface{}
    cons := val.(map[interface{}]interface{})
    for range cons {
        attr     = cons["attribute"]
        operator = cons["operator"]
        value    = cons["value"]

        switch operator {
            case "==":
                operator = "$eq"
            case "!=":
                operator = "$ne"
            case "()":
                operator = "$in"
        }
    }
        operations[attr.(string)] = bson.M{operator.(string): value}
}

Upvotes: 1

Related Questions