2

I have collection of documents Users

User { "Status": "ACTIVE", "Login": { "UserName": "login", "Password": null, "CreationDate": "2011-12-07T11:30:24.4062500Z", "Roles": [ { "Id": "roles/WebUser", "Name": "WebUser" }, { "Id": "roles/Admin", "Name": "Admin" } ] }, } 

How can i make a query to get list of users with role name "WebUser" except users with role name "Admin" (Contains role "WebUser" but not contains role "Admin")

Using LINQ or lucene

2 Answers 2

2

You need to create an index for that, something like:

from user in docs.Users select new { Roles = user.Logins.Roles.Select(x=>x.Name) } 

And then you can query is using:

Roles:WebMaster AND -Roles:Admin 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. It works with a small adjustment: from doc in docs.Users select new { RoleName = ((IEnumerable<dynamic>)doc.Login.Roles).Select(x=>x.Name)
Not sure if this syntax is antiquated but the - didn't work for me. I ended up having to use NOT Prop:Value but that alone didn't do the trick, I had to add the hack *:* AND NOT Prop:Value which I'm sure has to have some performance downside. Am I missing something?
@VinneyKelly, my observation was that field:bla AND (NOT Prop:Value) works when field:bla AND (-Prop:Value) did NOT. Looks like a bug in handling the brackets. Unfortunately, the .Not method gets transferred into - instead of NOT. Tested on v3.5
1

Is this what you want?

var users = documentSession.Query<User>() .Where(x => x.Login.Roles.Any(y => y.Name == "WebUser")) .Where(x => x.Login.Roles.Any(y => y.Name != "Admin")) .ToList(); 

sample unit test....

using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; using Raven.Client; using Raven.Client.Embedded; using Raven.Client.Linq; namespace Foo.Tests. { public class UserTests { [Test] // ReSharper disable InconsistentNaming public void GivenSomeUsersWithWebUserAndAdminRoles_Query_ReturnsSomeUsers() // ReSharper restore InconsistentNaming { IDocumentStore documentStore; using (documentStore = new EmbeddableDocumentStore {RunInMemory = true}) { // Arrange. documentStore.Initialize(); // Create and store Fake Data. using (IDocumentSession documentSession = documentStore.OpenSession()) { IEnumerable<User> users = CreateFakeUsers(documentSession); foreach (var user in users) { documentSession.Store(user); } documentSession.SaveChanges(); } using (IDocumentSession documentSession = documentStore.OpenSession()) { // Act. var users = documentSession.Query<User>() .Where(x => x.Login.Roles.Any(y => y.Name == "WebUser")) .Where(x => x.Login.Roles.Any(y => y.Name != "Admin")) .ToList(); // Assert. Assert.IsNotNull(users); Assert.AreEqual(2, users.Count); } } } private IEnumerable<User> CreateFakeUsers(IDocumentSession documentSession) { return new List<User> { new User { Status = "ACTIVE", Login = new Login { UserName = "loging", Password = null, CreationDate = DateTime.UtcNow, Roles = new List<Role> { new Role { Id = "roles/WebUser", Name = "WebUser" }, new Role { Id = "roles/Admin", Name = "Admin" } } } }, new User { Status = "ACTIVE", Login = new Login { UserName = "User 2", Password = null, CreationDate = DateTime.UtcNow, Roles = new List<Role> { new Role { Id = "roles/WebUser", Name = "WebUser" } } } }, new User { Status = "INACTIVE", Login = new Login { UserName = "User 3", Password = null, CreationDate = DateTime.UtcNow, Roles = new List<Role> { new Role { Id = "roles/Admin", Name = "Admin" } } } } }; } #region Nested type: Login private class Login { public string UserName { get; set; } public string Password { get; set; } public DateTime CreationDate { get; set; } public ICollection<Role> Roles { get; set; } } #endregion #region Nested type: Role private class Role { public string Id { get; set; } public string Name { get; set; } } #endregion #region Nested type: User private class User { public string Id { get; set; } public string Status { get; set; } public Login Login { get; set; } } #endregion } } 

1 Comment

No. Users that in role "WebUser" but not in role "Admin" (Not contains role "Admin") is what I want. In your example it is only the second user

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.