如何在动态循环中将多个查询过滤器组合在一起? MongoDB C#

时间:2017-02-25 17:53:39

标签: c# mongodb linq

这是我第一个使用MongoDB和NoSQL的项目,所以我知道我可能会在这里犯很多新手错误。好的,首先我将解释我正在处理的问题陈述。这是我在JSON集合中的产品的一个文档

{
    "_id" : ObjectId("58b19bb67425e833c4ca4a65"),
    "features" : [ 
        {
            "feature" : "Performance",
            "rating" : -1
        }, 
        {
            "feature" : "Speed",
            "rating" : -2
        }, 
        {
            "feature" : "Durability",
            "rating" : -1
        }
    ],
    "brand" : "EVGA",
    "stars" : 4,
    "productId" : "B01H0WU884",
    "productName" : "EVGA GeForce GTX 1070 SC GAMING ACX 30 8GB GDDR5 LED DX12 OSD Support PXOC Graphics Card 08G-P4-6173-KR",
    "productDescription" : "The EVGA GeForce GTX 1070 featuring EVGA ACX 3.0 cooling has arrived. This new graphics card features NVIDIA's new \"Pascal\" graphics processor which is the most advanced gaming GPU ever created.",
    "productCategory" : "Hardware",
    "productPrice" : "17000",
    "createdAt" : ISODate("2017-02-25T14:59:02.816Z"),
    "comments" : []
}

C#中的班级Product

public class Product
{

    public ObjectId id { get; set; }
    public string productId { get; set; }
    public string productName { get; set; }
    public string productDescription { get; set; }
    public string productCategory { get; set; }
    public string productPrice { get; set; }

    public DateTime createdAt { get; set; }

    public List<ProductFeature> features;
    public List<string> comments { get; set; }
    public string brand;
    public int stars;
}

班级ProductFeature

public class ProductFeature
{
    public string feature { get; set; }
    public int rating { get; set; }
}

这是我在JSON集合中的一个类别的文档

{
    "_id" : ObjectId("58b199627425e81e7c56eff1"),
    "Features" : [ 
        "Performance", 
        "Speed", 
        "Durability"
    ],
    "Name" : "Hardware"
}

C#中的课程Category

public class Category
{
    public List<string> Features { get; set; }
    public string Name { get; set; }
    public ObjectId id { get; set; }
}

现在,这就是我需要做的事情。 我有一个名为List<Category>的{​​{1}}列表。我需要选择集合中的产品,这些产品来自我在类别列表中的类别,其中我得到的每个产品必须至少有一个评级为&gt;的功能。 0,该功能也存在于附加到类别列表中每个类别的功能列表中。

我知道这似乎很复杂,这就是我需要帮助的原因。以下代码虽然不正确,但可以帮助您更好地理解。我需要知道如何使这段代码工作。我已经完全评论了我遇到的问题。

interests

这是我得到的例外

  

不支持的where子句:Enumerable.All(p.features,   (ProductFeature f)=&gt; ((f.feature ==“Performance”)&amp;&amp;(f.rating&gt; 0)))。

如果我在过滤器定义中放置 var query = null; // Error: Can't initialize 'var' object to null for (int i=0;i<interests.Count;i++) { var q1 = Query<Controller.Product>.Where(p => p.productCategory == interests[i].Name); var q2 = null; // Error: Can't initialize 'var' object to null for (int j=0;j<interests[i].Features.Count;j++) { // Exception on this next line var q3 = Query<Controller.Product>.Where(p => p.features.All(f => f.feature == interests[i].Features[j] && f.rating > 0)); q2 = Query.Or(q2, q3); } query = Query.Or(query, Query.And(q1, q2)); } var result = collection.Find(query).SetLimit(20); 而不是Any,则代码开始工作,但我需要All才能工作。 任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

根据示例,您将需要以下查询。

db.product.find({
    "productCategory": "Hardware",
    "features": {
        "$elemMatch": {
            "feature": {
                "$in": ["Performance",
                    "Speed",
                    "Durability"
                ]
            },
            "rating": {
                "$gt": 5
            }
        }
    }
})

以下是获取所有类别产品的简化C#代码

var pQuery = Query.Empty;
for (int i = 0; i < interests.Count; i++) {
    var cQuery = Query.And(
        Query<Product>.EQ(u => u.productCategory, interests[i].Name),
        Query<Product>.ElemMatch(f => f.features, e => Query.And(
            Query<ProductFeature>.In(u => u.feature, interests[i].Features),
            Query<ProductFeature>.GT(u => u.rating, 5))));
    pQuery = Query.Or(pQuery, cQuery);
}
var result = collection.Find(pQuery).SetLimit(20);
}