DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Implementing a Serverless DevOps Pipeline With AWS Lambda and CodePipeline
  • Operator Overloading in Java
  • How To Use Pandas and Matplotlib To Perform EDA In Python
  • Exploratory Testing Tutorial: A Comprehensive Guide With Examples and Best Practices

Trending

  • Implementing a Serverless DevOps Pipeline With AWS Lambda and CodePipeline
  • Operator Overloading in Java
  • How To Use Pandas and Matplotlib To Perform EDA In Python
  • Exploratory Testing Tutorial: A Comprehensive Guide With Examples and Best Practices
  1. DZone
  2. Data Engineering
  3. Data
  4. Searching Shouldn't Be So Hard

Searching Shouldn't Be So Hard

Implementing search into your UI? It doesn't have to be difficult for your user. Here are some things to consider when building a search capability for your users.

Oren Eini user avatar by
Oren Eini
·
Jan. 04, 17 · Opinion
Like (4)
Save
Tweet
Share
7.14K Views

Join the DZone community and get the full member experience.

Join For Free

The trigger for this post is a StackOverflow question that caught my eye.

Let us imagine that you have the following UI, and you need to implement the search function:

enter image description here

For simplicity’s sake, I’ll assume that you have the following class:

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

public class Address
{
public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int Postcode { get; set; }

}

And we need to implement this search, we want users to be able to search by the restaurant name, or its location or its cuisine, or all of the above, for that matter. A query such as”Rama Thai” or “coffee 48th st” should all give us results.

One way of doing that is to do something like this:

session.Query<Restaurant>()
.Where(x=>
x.Name == userSearchString ||
x.Cuisine == userSearchString ||
x.Address.Street == userSearchString ||
x.Address.City == userSearchString 
)
.ToList();

Of course, that would only find stuff that matches directly. It will find “Rama” or “Thai”, but “Rama Thai” would confuse it. We can make it better, somewhat, but doing a bit of work on the client side and changing the query, like so:

var parts =  userSearchString.Split();
session.Query<Restaurant>()
.Where(x=>
x.Name.In(userSearchString) ||
x.Cuisine.In(userSearchString) ||
x.Address.Street.In(userSearchString) ||
x.Address.City.In(userSearchString)
)
.ToList();

That would now find results for “Rama Thai”, right? But what about “Mr Korean” ? Consider a user who has no clue about the restaurant name, let alone how to spell it, but just remember enough pertinent information “it was Korean food and had a Mr in its name, on Fancy Ave”.

You can spend a lot of time trying to cater for those needs. Or you can stop thinking about the data you search as the same shape of your results and use this index:

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.Address.Street,   
                                     restaurant.Address.City,  
                                     restaurant.Name
                                   }
                               };

          Indexes.Add(x => x.Cuisine, FieldIndexing.Analyzed); 
      }
}

Note that what we are doing here is picking from the restaurant document all the fields that we want to search on and plucking them into a single location, which we then mark as analyzed. This let RavenDB know that it is time to start cranking. It merges all of those details together and arranges them in such a way that the following query can be done:

 var matches = session.Query<Restaurant_Search.Result, Restaurant_Search>()
      .Search(x => x.Query, "Fancy Mr Korean")
      .OfType<Restaurant>()
      .ToList();

And now we don’t do a field by field comparison, instead, we’ll apply the same analysis rules that we applied at indexing time to the query, after which we’ll be able to search the index. And now we have sufficient information not just to find this a restaurant named “Fancy Mr Korean” (which to my knowledge doesn’t exist), but to find the appropriate Korean restaurant in the appropriate street, pretty much for free.

Those kinds of features can dramatically uplift your applications’ usability and attractiveness to users. “This sites gets me”.

Database Comparison (grammar) Data (computing) POST (HTTP) Clue (mobile app) Merge (version control) Document Usability

Published at DZone with permission of Oren Eini, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Implementing a Serverless DevOps Pipeline With AWS Lambda and CodePipeline
  • Operator Overloading in Java
  • How To Use Pandas and Matplotlib To Perform EDA In Python
  • Exploratory Testing Tutorial: A Comprehensive Guide With Examples and Best Practices

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: