在使用Golang进行Mongo查询时出现了多个条件的问题。

huangapple go评论94阅读模式
英文:

Issue in mongo query with multiple conditions by using golang

问题

我有一个如下的文档 -

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

在这个文档中,properties 数组可以有多个元素。
当我通过我的 API 进行搜索时,
我通常会在我的 POST 请求的正文中传递一个类似于 properties 的数组 -

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

我有一个结构体来接收和解码这些信息 -

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"`
}

我还可以对各种 properties 进行 mongodb 的 $and 操作,只有当它们全部匹配时,才返回文档。
问题在于 properties 数组中的元素数量不固定。
我需要能够只发送以下内容

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

并检索所有匹配的文档(不仅仅是一个)。

我尝试使用一个循环来创建一个可变大小的 bson.M,取决于接收到的输入中 properties 数组的大小,但是我无法找到正确的方法来做到这一点!

应该如何处理这个问题?

英文:

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

得分: 2

我通过单独构建$and部分来实现了这一点 -

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)
}

然后我的查询看起来像这样 -

```go
c.Find(bson.M{"brandId": body.BrandID, "category": body.Category, "$and": AndQuery})
英文:

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

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

and then my query looked like -

c.Find(bson.M{&quot;brandId&quot;: body.BrandID, &quot;category&quot;: body.Category, &quot;$and&quot;: AndQuery})

huangapple
  • 本文由 发表于 2016年10月26日 16:09:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/40256945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定