You are currently browsing legacy 3.0 version of documentation. Click here to switch to the newest 4.2 version.

We can help you with migration to the latest RavenDB

Contact Us Now
see on GitHub

Intersection

To allow users to Intersect queries on the server-side and return only documents that match all the provided sub-queries we have introduced the query intersection feature.

Lets consider a case, where we have a T-Shirt class:

public class TShirt
{
	public string Id { get; set; }

	public int ReleaseYear { get; set; }

	public string Manufacturer { get; set; }

	public List<TShirtType> Types { get; set; }
}

public class TShirtType
{
	public string Color { get; set; }

	public string Size { get; set; }
}

And we fill our database with few records:

session.Store(new TShirt
{
	Id = "tshirts/1",
	Manufacturer = "Raven",
	ReleaseYear = 2010,
	Types = new List<TShirtType>
			{
				new TShirtType {Color = "Blue", Size = "Small"},
				new TShirtType {Color = "Black", Size = "Small"},
				new TShirtType {Color = "Black", Size = "Medium"},
				new TShirtType {Color = "Gray", Size = "Large"}
			}
});

session.Store(new TShirt
{
	Id = "tshirts/2",
	Manufacturer = "Wolf",
	ReleaseYear = 2011,
	Types = new List<TShirtType>
			{
				new TShirtType { Color = "Blue",  Size = "Small" },                                    
				new TShirtType { Color = "Black", Size = "Large" },
				new TShirtType { Color = "Gray",  Size = "Medium" }
			}
});

session.Store(new TShirt
{
	Id = "tshirts/3",
	Manufacturer = "Raven",
	ReleaseYear = 2011,
	Types = new List<TShirtType>
			{
				new TShirtType { Color = "Yellow",  Size = "Small" },
				new TShirtType { Color = "Gray",  Size = "Large" }
			}
});

session.Store(new TShirt
{
	Id = "tshirts/4",
	Manufacturer = "Raven",
	ReleaseYear = 2012,
	Types = new List<TShirtType>
			{
				new TShirtType { Color = "Blue",  Size = "Small" },
				new TShirtType { Color = "Gray",  Size = "Large" }
			}
});

Now we want to return all the T-shirts that are manufactured by Raven and contain both Small Blue and Large Gray types.

To do this, we need to do the following:

  • add Raven.Client namespace to usings
  • use Intersect query extension:

IList<TShirt> results = session.Query<TShirts_ByManufacturerColorSizeAndReleaseYear.Result, TShirts_ByManufacturerColorSizeAndReleaseYear>()
	   .Where(x => x.Manufacturer == "Raven")
	   .Intersect()
	   .Where(x => x.Color == "Blue" && x.Size == "Small")
	   .Intersect()
	   .Where(x => x.Color == "Gray" && x.Size == "Large")
	   .OfType<TShirt>()
	   .ToList();
IList<TShirt> results = session
	.Advanced
	.DocumentQuery<TShirt, TShirts_ByManufacturerColorSizeAndReleaseYear>()
	.WhereEquals("Manufacturer", "Raven")
	.Intersect()
	.WhereEquals("Color", "Blue")
	.AndAlso()
	.WhereEquals("Size", "Small")
	.Intersect()
	.WhereEquals("Color", "Gray")
	.AndAlso()
	.WhereEquals("Size", "Large")
	.ToList();
QueryResult result = store
	.DatabaseCommands
	.Query(
		"TShirts/ByManufacturerColorSizeAndReleaseYear",
		new IndexQuery
		{
			Query = "Manufacturer:Raven INTERSECT Color:Blue AND Size:Small INTERSECT Color:Gray AND Size:Large"
		});
public class TShirts_ByManufacturerColorSizeAndReleaseYear : AbstractIndexCreationTask<TShirt>
{
	public class Result
	{
		public string Manufacturer { get; set; }

		public string Color { get; set; }

		public string Size { get; set; }

		public int ReleaseYear { get; set; }
	}

	public TShirts_ByManufacturerColorSizeAndReleaseYear()
	{
		Map = tshirts => from tshirt in tshirts
						 from type in tshirt.Types
						 select new
							{
								Manufacturer = tshirt.Manufacturer,
								Color = type.Color,
								Size = type.Size,
								ReleaseYear = tshirt.ReleaseYear
							};
	}
}

Above query will return tshirts/1 and tshirts/4 as a result. Document tshirts/2 will not be included, because it is not manufactured by Raven and tshirts/3 is not available in Small Blue so it does not match all the sub-queries.