[英]Use LINQ in C# to find MondoDB records when values in a list field match a criteria value from a list
I want to use LINQ to return all records in a MongoDB collection where the field in the record is a list of strings and any string in the list matches any string value in a list of strings used as the search criteria: 我想使用LINQ返回MongoDB集合中的所有记录,其中记录中的字段是字符串列表,列表中的任何字符串都与用作搜索条件的字符串列表中的任何字符串值匹配:
Mongo Record in Collection ("Item"): 集合中的Mongo记录(“项目”):
{
"_id": ...,
"StringList": [
"string1",
"string2",
"string3"
],
...
}
Search Criteria: 搜索条件:
var criteria = new List<string> { "string2", "string4" };
My Code: 我的代码:
var foundItems = iMongoDataProvider.FindAll<Item>()
.Where(x =>x.StringList.ContainsAny(criteria)).ToList();
Based on the above, the Mongo record should be returned since one of the StringList values matches one of the values in the search criteria . 基于上述内容,由于StringList值之一与搜索条件中的值之一匹配,因此应返回Mongo记录。 Nothing is returned even though I can manually peruse the collection and find the matching record.
即使我可以手动细读集合并找到匹配的记录,也不会返回任何内容。 What am I doing wrong?
我究竟做错了什么? Can someone provide an example that will do what I need?
有人可以提供一个可以满足我需要的示例吗? Thanks!
谢谢!
have you tried somethinglike: 您是否尝试过类似的方法:
using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System.Linq;
using System.Linq.Expressions;
var foundItems = _collection.FindAll(x=> criteria.Any(cc=> xx.StringList.Contains(cc))).ToList();
Where _collection
is IMongoCollection<TEntity> _collection
其中
_collection
是IMongoCollection<TEntity> _collection
What you are looking for is ElemMatch
Filter ( https://docs.mongodb.com/v3.2/reference/operator/query/elemMatch/ ) : 您正在寻找的是
ElemMatch
筛选器( https://docs.mongodb.com/v3.2/reference/operator/query/elemMatch/ ):
var foundItems = collection.Find(Builders<Item>.Filter.ElemMatch(
x => x.StringList,
s=>criteria.Contains(s)));
where collection is your IMongoCollection<Item>
I see, that you are using FindAll
, that means, that your MongoDb driver is of the version 1.x (see here more about it: FindAll in MongoDB .NET Driver 2.0 ) I would suggest to update your driver, because this version isnot uptodate. 我建议您在哪里使用
IMongoCollection<Item>
集合,即您正在使用FindAll
,这意味着您的MongoDb驱动程序的版本为1.x(请参见此处的更多信息: MongoDB .NET Driver 2.0中的FindAll ),我建议更新您的驱动程序,因为此版本不是最新的。 Or are the any important reason don't to do it? 还是有重要原因不这样做?
This filter query on server. 服务器上的此过滤器查询。 Sure you could get your data as IEnumerable and filter it locally:
确保您可以将数据获取为IEnumerable并在本地进行过滤:
var foundItems = collection.Find(x=>true)
.ToEnumerable()
.Where(x => x.StringList.Intersect(criteria).Any());
If your data is not so huge and you are fine with filtering on client it's a good way too. 如果您的数据不是很大,并且可以对客户端进行筛选,那么这也是一种好方法。
And if you are doing already FindAll
, that means you get get all the data, you could query it with intersect
: 如果您已经在执行
FindAll
,这意味着您将获取所有数据,则可以使用intersect
查询:
var foundItems = iMongoDataProvider.FindAll<Item>()
.Where(x => x.StringList.Intersect(criteria).Any());
What you want is to know if the intersection of the two lists has any values: 您要知道两个列表的交集是否具有任何值:
.Where(x =>x.StringList.Intersect(criteria).Any())
I'm not sure what the problem is with your code but here is working code 我不确定您的代码出了什么问题,但这是工作代码
void Main()
{
List<string> []StringList = new List<string>[] {
new List<string> { "string1", "string2", "string3" },
new List<string> { "string11", "string12", "string13" },
new List<string> { "string21", "string22", "string4" }
};
var criteria = new List<string> { "string2", "string4" };
var foundItems = StringList
.Where(x => x.Intersect(criteria).Any()).ToList();
foundItems.Dump();
}
I tested this using LinqPad (which I recommend to anyone working in Linq and it is free). 我使用LinqPad进行了测试(我向使用Linq的任何人推荐它,并且它是免费的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.