【问题标题】:MongoDB selecting records which match value in arrayMongoDB选择与数组中的值匹配的记录
【发布时间】:2019-06-13 04:36:03
【问题描述】:

我对 MongoDb 真的很陌生,我有两个 Mongodb 文档 Role 和 User

角色

{"_id":"5d0124b858d49243306deaa2",   
"mdt":"2019-06-12T16:13:44.037Z",
"mby":"000000000000000000000000",
"IsDeleted":false,
"Name":"Manager"}

我的另一个文档是具有以下定义的用户,用户可以拥有多个角色。

用户

{ 
  "firstName" : "John",
  "lastName" : "Doe",
  "Role" : {"5d0124b858d49243306deaa2", "6d0125b858749243306deaa2", "9b0124a852d49245306deba2"} \\ Array of role Id's assigned to users
}

如何使用 MongoDB .Net 驱动程序和 Linq 查询具有匹配角色的用户的名字和姓氏。

可能听起来很有趣,但我尝试了下面这样的小事

public List<User> GetCaseAssigneesByRoles(string roles)
        {

            return User.Query.Find(User.Query.EQ(a=>a.FirstName, roles)).ToList();
        } 

【问题讨论】:

  • 如果您是新手,最好的办法是找到与您想做的事情相似的示例。如果您不确定从哪里开始,那么文档绝不是一个糟糕的地方。 Mongo 的文档非常好。无论如何,我通常使用过滤器构建器构建我的查询,在那里我会使用.In(...)。这似乎对应于this question/answer 中的LINQ。显然检查名字/姓氏是否相等。
  • @John 我真的很害羞分享我尝试过的更新问题。\
  • 你应该总是展示你尝试过的东西,即使它是错误的。 1) 它有时有助于明确你的目标,以及 2) 它表明你自己确实尝试过一些东西,而且你不只是期望我们为你做你的工作。我很感激 2) 不是你的目标,但有些人确实带着这个目标来到这里。
  • string roles的内容是什么?这是角色名吗?
  • 那么当您搜索角色名称(而不是 id)时,您想要一个全名列表吗?

标签: c# mongodb linq mongodb-query mongodb-.net-driver


【解决方案1】:

您应该能够像这样查询用户:

public List<User> GetCaseAssigneesByRoles(string role)
{
    return UserCollection
        .Find(Builders<User>.Filter.AnyEq(u => u.Roles, role))
        .ToEnumerable()
        .ToList();
}

基本上AnyEq 接受一个数组 (Roles) 并检查列表中是否有任何单个项目等于您指定的值。您可能需要更改此示例中的某些字段名称。

或者对于角色列表(单个角色必须匹配):

public List<User> GetCaseAssigneesByRoles(List<string> roles)
{
    return UserCollection
        .Find(Builders<User>.Filter.AnyIn(u => u.Roles, roles))
        .ToEnumerable()
        .ToList();
}

或者对于角色列表(其中所有角色必须匹配):

public List<User> GetCaseAssigneesByRoles(List<string> roles)
{
    return UserCollection
        .Find(Builders<User>.Filter.All(u => u.Roles, roles))
        .ToEnumerable()
        .ToList();
}

【讨论】:

  • 会试试这个,想问我可以通过角色列表而不是角色吗?
  • @Vijay 在这种情况下所有角色都必须匹配,还是只有一个?
  • 列表中的所有卷都不匹配,它必须返回用户名。
  • 好的,选择合适的查询并试一试。如果您有任何问题,请告诉我。 :-)
  • 当然,约翰,谢谢
【解决方案2】:

这是使用库MongoDB.Entities 使用 LINQ 的一种简单方法 [免责声明:我是作者]

using MongoDB.Entities;
using MongoDB.Driver.Linq;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class User : Entity
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string[] Roles { get; set; }
        }

        public class Role : Entity
        {
            public string Name { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            var managerRole = new Role { Name = "Manager" };
            var superRole = new Role { Name = "Supervisor" };

            managerRole.Save();
            superRole.Save();

            var user = new User
            {
                FirstName = "John",
                LastName = "Doe",
                Roles = new[] { managerRole.ID, superRole.ID }
            };

            user.Save();

            var findRoles = new[] { managerRole.ID, superRole.ID };

            var managers = DB.Queryable<User>()
                             .Where(u => u.Roles.Any(r => findRoles.Contains(r)))
                             .Select(u => u.FirstName + " " + u.LastName)
                             .ToArray();
        }
    }
}

这是它发送到 mongodb 的聚合查询:

db.User.aggregate([{
    "$match": {
        "Roles": {
            "$elemMatch": {
                "$in": ["5d02691bada517167415c326", "5d02691cada517167415c327"]
            }
        }
    }
}, {
    "$project": {
        "__fld0": {
            "$concat": ["$FirstName", " ", "$LastName"]
        },
        "_id": 0
    }
}])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多