jenna_3108
jenna_3108

Reputation: 435

How to perform search in RavenDB and ASP.NET MVC?

I am trying to perform a search query using RavenDB and ASP.NET MVC. I want to be able to search restaurant using Name, Cuisine, City or State. So I have created the indexes Restaurants_ByName Restaurants_ByCuisine Restaurants_ByCity Restaurants_ByState in Index folder. Now I am not sure how to use the search function in my Search.cshtml

Model - Restaurant.cs

  public class Restaurant
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Cuisine { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int Postcode { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
}

Indexes - Search.cs

 public class Searching
{
    public class Restaurants_ByName : AbstractIndexCreationTask<Restaurant>
    {
        public Restaurants_ByName()
        {
            Map = restaurants => from restaurant in restaurants
                                 select new
                                 {
                                     restaurant.Name
                                 };
            //Indexes.Add(x = x.Name, FieldIndexing.Analyzed);
        }
    }

    public class Restaurant_ByCuisine : AbstractIndexCreationTask<Restaurant>
    {
        public Restaurant_ByCuisine()
        {
            Map = restaurants => from restaurant in restaurants
                                 select new
                                 {
                                     restaurant.Cuisine
                                 };
            //Indexes.Add(x = x.Cuisine, FieldIndexing.Analyzed);
        }
    }

    public class Restaurant_ByCity : AbstractIndexCreationTask<Restaurant>
    {
        public Restaurant_ByCity()
        {
            Map = restaurants => from restaurant in restaurants
                                 select new
                                 {
                                     restaurant.City
                                 };
            //Indexes.Add(x = x.City, FieldIndexing.Analyzed);
        }
    }

    public class Restaurant_ByState : AbstractIndexCreationTask<Restaurant>
    {
        public Restaurant_ByState()
        {
            Map = restaurants => from restaurant in restaurants
                                 select new
                                 {
                                     restaurant.State
                                 };
            //Indexes.Add(x = x.State, FieldIndexing.Analyzed);
        }
    }

    public Searching(string searchString)
    {
        using (var store = new DocumentStore
        {
            Url = "http://localhost:8080/",
            DefaultDatabase = "foodfurydb"
        })
        {
            store.Initialize();

            using (var session = store.OpenSession())
            {
                // using query
                IList<Restaurant> restaurants = session
                    .Query<Restaurant, Restaurants_ByName>()
                    .Where(x => x.Name == searchString)
                    .ToList();
            }
        }
    }
}

I need to do something in my controller right?

public ActionResult SearchRestaurant()
    {
        using (var store = new DocumentStore
        {
            Url = "http://localhost:8080/",
            DefaultDatabase = "foodfurydb"
        })
        {
            store.Initialize();

            using (var session = store.OpenSession())
            {

            }
        }
        return View();
    }

Partial View - SearchRestaurant.cshtml

    <div class="row">
    <div class="input-field col s12" id="search-bar">
        <i class="material-icons prefix">search</i>
        <input placeholder="Search by restaurant name / cuisine / location" id="search-restaurant"/>
    </div>
</div>

Edit

What I'm trying to achieve is by typing name/cuisine/location it will return the relevant results

enter image description here

Upvotes: 1

Views: 424

Answers (1)

Ayende Rahien
Ayende Rahien

Reputation: 22956

Don't create a separate index for property, it isn't efficient. And you are better off in searching across all of them at once.

The index will look like this:

public class Restaurant_Search : AbstractIndexCreationTask<Restaurant, Restaurant_Search.Result>
 {
        public class Result
        {
           public string Query;
        }

        public Restaurant_ByCuisine()
        {
            Map = restaurants => from restaurant in restaurants
                                 select new
                                 {
                                     Query = new []
                                     {
                                       restaurant.Cuisine, 
                                       restaurant.State,   
                                       restaurant.City,  
                                       restaurant.Name
                                     }
                                 };

            Indexes.Add(x => x.Cuisine, FieldIndexing.Analyzed); // => instead of = (previously)
        }
 }

You would then query it using:

using (var session = store.OpenSession())
{
   var matches = session.Query<Restaurant_Search.Result, Restaurant_Search>()
      .Search(x => x.Query, "new york indian")
      .OfType<Restaurant>()
      .ToList();
}

Note that you can now both search across all those fields and the the kind of queries the user can provide are a lot more interesting.

Upvotes: 2

Related Questions