简体   繁体   English

MongoDB C#查找文件清单 <string> 包含另一个列表的值 <string>

[英]MongoDB C# Find documents where List<string> contains value of another List<string>

In the process of creating a filtering feature in my mongoDB i have created the following find query using the mongoDB driver for c#. 在我的mongoDB中创建过滤功能的过程中,我已使用用于c#的mongoDB驱动程序创建了以下查找查询。

return await DefaultCollection
                .Find(c => c.vintageInfo.IsVintage
                           && c.IsPublished
                           && c.AverageRating >= lowerRating
                           && filterArray1.Contains(c.filterSearchParameters.Dosage))       
                .Skip(page * pageSize)
                .Limit(pageSize)
                .ToListAsync();

This is working perfect and it's all great! 这是完美的工作,一切都很好!

Now as we see in the example above i can check if the provided filterArray1 contains the document attribute c.filterSearchParameters.Dosage. 现在,如我们在上面的示例中看到的,我可以检查所提供的filterArray1是否包含文档属性c.filterSearchParameters.Dosage。 Now the problem arises cause, the document further contains a list as follows c.filterSearchParameters.Styles. 现在出现问题的原因,文档进一步包含c.filterSearchParameters.Styles列表。 What i would like to be able to do is check if the list c.filterSearchParameters.Styles contains any value matching filterArray2. 我想做的是检查列表c.filterSearchParameters.Styles是否包含任何与filterArray2匹配的值。

Edit 编辑

As per request: 按要求:

filterSearchParameters looks like: filterSearchParameters看起来像:

public class FilterSearchParameters
    {
        public string Dosage { get; set; }
        public List<string> Style { get; set; }
        public List<string> Character { get; set; }
    }

and the filterArray1 and 2 is just an ordinary: 而filterArray1和2只是一个普通的:

List<string> filterArray1
List<string> filterArray2

To do this i tried: 为此,我尝试过:

return await DefaultCollection
                .Find(c => c.vintageInfo.IsVintage
                           && c.IsPublished
                           && c.AverageRating >= lowerRating
                           && filterArray1.Contains(c.filterSearchParameters.Dosage)
                           && filterArray2.Any(x => c.filterSearchParameters.Style.Any(y => y.Equals(x))))      
                .Skip(page * pageSize)
                .Limit(pageSize)
                .ToListAsync();

Adding the line: 添加行:

filterArray2.Any(x => c.filterSearchParameters.Style.Any(y => y.Equals(x)))

However this throws Unsopported filter exception. 但是,这会引发非支持的过滤器异常。 So i tried: 所以我试着:

return await DefaultCollection
                .Find(c => c.vintageInfo.IsVintage
                           && c.IsPublished
                           && c.AverageRating >= lowerRating
                           && filterArray1.Contains(c.filterSearchParameters.Dosage)
                           && c.filterSearchParameters.Style.Intersect(filterArray2).Any())     
                .Skip(page * pageSize)
                .Limit(pageSize)
                .ToListAsync();

Adding the line : 添加行:

c.filterSearchParameters.Style.Intersect(filterArray2).Any()

However the error persisted... 但是错误仍然存​​在...

Lastly ive found -> 最后找到我->

Builders<Entity>.Filter.ElemMatch(
        x => x.filterSearchParameters.Style,
        s => filterArray2.Contains(s))

But havn't been able to incorporate it and try it out with the other filters. 但是还无法将其合并并与其他过滤器一起试用。

Does anyone know how to solve this problem, or any knowledge that could point me in the direction of some documentation i could read, or say if i'm already looking in the wrong place... Any help is appreaciated, thanks in advance. 是否有人知道如何解决此问题,或者是否有任何知识可以将我指向我可以阅读的某些文档的方向,或者说我是否已经在错误的位置找到了……感谢您的帮助,在此感谢您。

In your data model Style property is a regular .NET List which can be serialized and deserialized to MongoDB. 在您的数据模型中, Style属性是一个常规的.NET List,可以将其序列化并反序列化到MongoDB。 The drawback is that even though you can see LINQ Extension methods like Any or Intersect , those method cannot be converted into database query. 缺点是,即使您可以看到LINQ Extension方法(例如AnyIntersect ,也无法将这些方法转换为数据库查询。 That's why it fails in the runtime. 这就是它在运行时失败的原因。

To match two arrays in MongoDB you can simply use $in operator 要匹配MongoDB中的两个数组,您只需使用$ in运算符

You can try below example in Mongo shell: 您可以在Mongo Shell中尝试以下示例:

db.col.save({ a : [1,3,4]})
db.col.find({ a : { $in: [1,2]})

It works in Mongo query language and you have to do the same thing in C#. 它可以在Mongo查询语言中使用,并且您必须在C#中执行相同的操作。 Because of that Mongo C# driver introduces AnyIn generic method which expects two generic IEnumerable parameters, first one from your data model and second one as a parameter type. 因此,Mongo C#驱动程序引入了AnyIn泛型方法,该方法需要两个泛型IEnumerable参数,第一个是数据模型中的参数,第二个是参数类型。

public FilterDefinition<TDocument> AnyIn<TItem>(Expression<Func<TDocument, IEnumerable<TItem>>> field, IEnumerable<TItem> values);

You can use Builders to create such expression: 您可以使用Builders创建这样的表达式:

Expression<Func<YourTypeClass, bool>> p = c => c.vintageInfo.IsVintage
                  && c.IsPublished
                  && c.AverageRating >= lowerRating
                  && filterArray1.Contains(c.filterSearchParameters.Dosage);

var filterBuilder = Builders<YourTypeClass>.Filter;

var filter = filterBuilder.AnyIn(x => x.filterSearchParameters.Style, filterArray2);

return await DefaultCollection
    .Find(filterBuilder.And(filter, p))
    .Skip(page * pageSize)
    .Limit(pageSize)
    .ToListAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM