繁体   English   中英

当列表字段中的值与列表中的条件值匹配时,在C#中使用LINQ查找MondoDB记录

[英]Use LINQ in C# to find MondoDB records when values in a list field match a criteria value from a list

我想使用LINQ返回MongoDB集合中的所有记录,其中记录中的字段是字符串列表,列表中的任何字符串都与用作搜索条件的字符串列表中的任何字符串值匹配:

集合中的Mongo记录(“项目”):

{
    "_id": ...,
    "StringList": [
        "string1",
        "string2",
        "string3"
    ],
    ...
}

搜索条件:

var criteria = new List<string> { "string2", "string4" };

我的代码:

var foundItems = iMongoDataProvider.FindAll<Item>()
                           .Where(x =>x.StringList.ContainsAny(criteria)).ToList();

基于上述内容,由于StringList值之一与搜索条件中的值之一匹配,因此应返回Mongo记录。 即使我可以手动细读集合并找到匹配的记录,也不会返回任何内容。 我究竟做错了什么? 有人可以提供一个可以满足我需要的示例吗? 谢谢!

您是否尝试过类似的方法:

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();

其中_collectionIMongoCollection<TEntity> _collection

您正在寻找的是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)));

我建议您在哪里使用IMongoCollection<Item>集合,即您正在使用FindAll ,这意味着您的MongoDb驱动程序的版本为1.x(请参见此处的更多信息: MongoDB .NET Driver 2.0中的FindAll ),我建议更新您的驱动程序,因为此版本不是最新的。 还是有重要原因不这样做?

服务器上的此过滤器查询。 确保您可以将数据获取为IEnumerable并在本地进行过滤:

var foundItems = collection.Find(x=>true)
                   .ToEnumerable()
                   .Where(x => x.StringList.Intersect(criteria).Any());

如果您的数据不是很大,并且可以对客户端进行筛选,那么这也是一种好方法。

如果您已经在执行FindAll ,这意味着您将获取所有数据,则可以使用intersect查询:

var foundItems = iMongoDataProvider.FindAll<Item>()
                           .Where(x => x.StringList.Intersect(criteria).Any());

您要知道两个列表的交集是否具有任何值:

 .Where(x =>x.StringList.Intersect(criteria).Any())

我不确定您的代码出了什么问题,但这是工作代码

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

我使用LinqPad进行了测试(我向使用Linq的任何人推荐它,并且它是免费的)。

暂无
暂无

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

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