Skip to content

Instantly share code, notes, and snippets.

Created April 23, 2012 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/2473684 to your computer and use it in GitHub Desktop.
Save anonymous/2473684 to your computer and use it in GitHub Desktop.
RavenDB.Index.SelectMany
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using Raven.Abstractions.Indexing;
using Raven.Client;
using Raven.Client.Document;
using Raven.Client.Embedded;
using Raven.Client.Indexes;
using Raven.Client.Linq;
using Raven.Database.Server;
using Raven.Json.Linq;
namespace RavenDBSample
{
public class SimpleFullTextSearch
{
private static void Main(string[] args)
{
var documentStore = new EmbeddableDocumentStore
{
RunInMemory = true,
};
documentStore.Initialize();
// Create the index.
IndexCreation.CreateIndexes(typeof(ProductsSearch).Assembly, documentStore);
// Create some fake data.
SeedFakeData(documentStore);
// Open ManagementCenter to verify index & data is created
WaitForUserToContinue(documentStore);
// Now lets search.
Console.WriteLine("searching for the query: Notebook");
Console.WriteLine("Should return 2 procuts");
Search(documentStore, "Notebook");
}
private static void SeedFakeData(IDocumentStore documentStore)
{
if (documentStore == null)
{
throw new ArgumentNullException("documentStore");
}
using (var session = documentStore.OpenSession())
{
// First product
var firstProduct = new Product
{
Title = "A Notebook from HP",
Tags = new List<Tag>
{
new Tag
{
Name = "HP",
Aliases = new List<Tag> { new Tag {Name = "Hewlett Packard"} }
},
new Tag
{
Name = "Notebook",
Aliases = new List<Tag> { new Tag {Name = "Laptop"} }
}
}
};
// Second Product
var secondProduct = new Product
{
Title = "A Notebook from Lenovo",
Tags = new List<Tag>
{
new Tag {Name = "Lenovo"},
new Tag
{
Name = "Notebook",
Aliases = new List<Tag> { new Tag {Name = "Laptop"} }
}
}
};
session.Store(firstProduct);
session.Store(secondProduct);
session.SaveChanges();
}
}
private static void Search(IDocumentStore documentStore, string query)
{
if (documentStore == null)
{
throw new ArgumentNullException("documentStore");
}
if (string.IsNullOrEmpty(query))
{
throw new ArgumentNullException("query");
}
using (var session = documentStore.OpenSession())
{
// Now lets chain the searching.
var products = session.Query<ProductsSearch.Result, ProductsSearch>()
.Customize(x => x.WaitForNonStaleResults())
.SearchMultiple(x => x.Query, query, options: SearchOptions.And)
.As<Product>()
.ToList();
Console.WriteLine("Found {0} results.", products.Count);
foreach (var product in products)
{
Console.WriteLine("Product => Id: {0}, Name: {1}, TagsCound: {2}",
product.Id, product.Title, product.Tags.Count);
}
}
}
private static void WaitForUserToContinue(EmbeddableDocumentStore documentStore)
{
if (Debugger.IsAttached == false)
return;
documentStore.DatabaseCommands.Put("Pls Delete Me", null,
RavenJObject.FromObject(new { StackTrace = new StackTrace(true) }),
new RavenJObject());
documentStore.Configuration.AnonymousUserAccessMode = AnonymousUserAccessMode.All;
using (var server = new HttpServer(documentStore.Configuration, documentStore.DocumentDatabase))
{
server.StartListening();
Process.Start(documentStore.Configuration.ServerUrl); // start the server
do
{
Thread.Sleep(100);
} while (documentStore.DatabaseCommands.Get("Pls Delete Me") != null && Debugger.IsAttached);
}
}
}
public class Product
{
public Product()
{
Tags = new List<Tag>();
}
public string Id { get; set; }
public string Title { get; set; }
public IList<Tag> Tags { get; set; }
}
public class Tag
{
public Tag()
{
Aliases = new List<Tag>();
}
public string Name { get; set; }
public IList<Tag> Aliases { get; set; }
}
public class ProductsSearch : AbstractIndexCreationTask<Product, ProductsSearch.Result>
{
public class Result
{
public string Query { get; set; }
}
public ProductsSearch()
{
Map = products => from product in products
select new
{
Query = new object[]
{
product.Title,
product.Tags.Select(tag => tag.Name),
product.Tags.SelectMany(tag => tag.Aliases, (tag, alias) => alias.Name)
}
};
Index(x => x.Query, FieldIndexing.Analyzed);
}
public override string IndexName
{
get
{
return "Products/Search";
}
}
}
public static class RavenQueryableExtensions
{
public static IRavenQueryable<T> SearchMultiple<T>(this IRavenQueryable<T> self,
Expression<Func<T, object>> fieldSelector, string queries,
decimal boost = 1, SearchOptions options = SearchOptions.Or)
{
if (string.IsNullOrEmpty(queries))
{
throw new ArgumentNullException("queries");
}
var searchValues = queries.Split(' ');
return self.SearchMultiple(fieldSelector, searchValues, boost, options);
}
public static IRavenQueryable<T> SearchMultiple<T>(this IRavenQueryable<T> self,
Expression<Func<T, object>> fieldSelector, IEnumerable<string> queries,
decimal boost = 1, SearchOptions options = SearchOptions.Or)
{
if (queries == null)
{
throw new ArgumentNullException("queries");
}
return queries.Aggregate(self, (current, query) => current.Search(fieldSelector, query, boost, options));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment