1

I have a document as follows -

{ 
    "_id" : "580eef0e4dcc220df897a9cb", 
    "brandId" : 15, 
    "category" : "air_conditioner", 
    "properties" : [
        {
            "propertyName" : "A123", 
            "propertyValue" : "A123 678"
        }, 
        {
            "propertyName" : "B123", 
            "propertyValue" : "B123 678"
        }, 
        {
            "propertyName" : "C123", 
            "propertyValue" : "C123 678"
        }
    ]
}

In this, the properties array can have multiple number of elements. When I perform a search via my API, I would ideally pass an array similar to properties in the body of my POST request -

{ 
    "brandId" : 15, 
    "category" : "air_conditioner", 
    "properties" : [
        {
            "propertyName" : "A123", 
            "propertyValue" : "A123 678"
        }, 
        {
            "propertyName" : "B123", 
            "propertyValue" : "B123 678"
        }, 
        {
            "propertyName" : "C123", 
            "propertyValue" : "C123 678"
        }
    ]
}

I have a struct to receive and decode this information -

type Properties struct {
    PropertyName  string `json:"propertyName" bson:"propertyName"`
    PropertyValue string `json:"propertyValue" bson:"propertyValue"`
}

type ReqInfo struct {
    BrandID      int             `json:"brandId" bson:"brandId"`
    Category     string          `json:"category" bson:"category"`
    Properties   []Properties    `json:"properties" bson:"properties"`
}

I can also perform a mongodb $and operation over the various properties and only when all of them match, the document is returned. The problem here is that the number of elements in the properties array is not fixed. I need to be able to send just

{ 
    "brandId" : 15, 
    "category" : "air_conditioner", 
    "properties" : [
        {
            "propertyName" : "A123", 
            "propertyValue" : "A123 678"
        }
    ]
}

and retrieve all the matching documents (not just one).

I tried my hand at creating a variable size bson.M using a for loop depending on the size of the properties array being received as the input but couldn't get the right way to do it!

How should this be approached?

1 Answer 1

2

I was able to achieve this by constructing the $and part separately -

var AndQuery []map[string]interface{}
for i := 0; i < len(body.Properties); i++ {
    log.Println(body.Properties[i])
    currentCondition := bson.M{"properties": bson.M{"$elemMatch": bson.M{"propertyName": body.Properties[i].PropertyName, "propertyValue": body.Properties[i].PropertyValue}}}
    AndQuery = append(AndQuery, currentCondition)
}

and then my query looked like -

c.Find(bson.M{"brandId": body.BrandID, "category": body.Category, "$and": AndQuery})
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.