What are the steps for building a faceted search solution with RavenDB? - ravendb

I need to build a new search solution for our website that will allow users to quickly locate products that match their needs. We want to use a faceted "Amazon.com" type of search and I want to implement using RavenDB. Can anyone help me with defining at a high-level what the steps are to accomplish this from beginning to end. I have already figured out a few of them and I have also determined that I am going to have to make use of Dynamic Fields. So here are the steps that I know of. Any advice/direction/clarification would be greatly appreciated.
Download and install RavenDB
Setup the RavenDB Server (I have chosen to run under IIS)
Create object(s) to store data. I know I am going to need to make use of Dynamic Fields since products can have different attributes. My current objects look like this:
public class ProductSeries
{
public Guid UID { get; set; }
public String SeriesName { get; set; }
public String SeriesDescription { get; set; }
public String ProductIDInCMS { get; set; }
public List<ProductAttribute> Attributes { get; set; }
}
public class ProductAttribute
{
public string Attribute { get; set; }
public string Value { get; set; }
}
Store documents in database.
Create indexes??? Here's where I get lost. Is this the next step?
...
???
Ultimately, I know I will conclude with creating some sort of AJAX enabled control that will display facets with their values and counts and allow users to make selections that will filter our thousands of products down to a select few that meet their criteria. I think I know where I start and where I finish; it's what happens in between that has me stumped.

Did you read the docs about this?
They explain all of it: http://ravendb.net/docs/2.5/client-api/faceted-search

Related

Confused about DTOs when reading and editing. How to desing DTO for filling the form in VUEjs app?

I am trying to develop an enterprise-level application. I have domain and application services. I have created my DTOs for multiple purposes separately. But confused about which way I should use them from the API viewpoint.
I have complex objects lets say,
public class Entity{
public int Id { get; set; }
public string Name { get; set; }
public int? ManufacturerId { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
public class Manufacturer{
public int Id { get; set; }
public string Text { get; set; }
}
And I have corresponding DTOs designed with composition now. It was separated before.
public class EntityBaseDto{
public string Name { get; set; }
}
public class EntityReadDto : EntityBaseDto{
public string Manufacturer { get; set; }
}
public class EntityWriteDto : EntityBaseDto{
public int? ManufacturerId { get; set; }
}
Now the question is,
I have a table which is filled with List<EntityReadDto> which is clear. Before, EntityReadDto also had the ManufacturerDto as fully included with id and text. Whenever I require to edit one of the entries from the table I was able to load the dropdown selected items or list of tags etc with the ids attached to the Manufacturer objects within ReadDtos. Now it is not possible. Since I wanted to simplify the codes I just converted them to strings that are read-only. Now I have created another endpoint to get an editable version of the record when needed. Ex: EntityWriteDto will be used to fill the form when the edit is clicked on a specific item. The manipulation will be carried on that DTO and sent with the PUT type request to edit the record.
I am not sure if this approach is ok for these cases. What is the best practice for this? I have many objects related to the entities from other tables. Is it ok to make a call to get an editable version from the backend or need to have it right away in a VUEjs app?

Returning a document and its path in a hierarchy using RavenDB

I am using RavenDB for the first time as a database for a website. I am just starting out and thinking about how to represent the page website hierarchy in the database. I read this article Modelling hierarchical data with RavenDB and it shows a really neat way of storing a hierarchy in a document database and hence I am running with this design.
So I have my Page document
public class Page
{
public string Id { get; set; }
public string Slug { get; set; }
}
and my PagesHierarchy document.
public class PagesHierarchyTree
{
public class Node
{
public string PageId { get; set; }
public List<Node> Children { get; set; }
}
public List<Node> RootPages { get; set; }
}
The idea is to have the PagesHierarchyTree represent the tree and this document has reference id's to the actual documents.
So, now to my question. I want to create an index where I can find a document (page) based on the slug but also return the slug path i.e a/b/c based on where the document lives in the tree.
I read about Indexing Hierarchical Data and Indexing Related Documents but i`m struggling to bring them together.
Can someone help me with this or point me in the right direction?
I got my answer from the ravendb google groups forum found here.

asp.net web api controllers accept POCO or generic data

I am new with ASP.NET Web API and have been researching this for some time now. Admittedly, I have decision paralysis. I want to make a REST-like API for a system with about 250 tables in the database. It's basically a 2 tier system with a UI and a data access layer, not using business objects or ORM.
I cannot decide if my Web API Controllers should accept/return:
a) IDictionary of name/value pairs, which I would package into sql parameters and pass to the data access layer and return a serialized ado.net data table
b) strongly typed complex object (POCO objects). For example: Account class with all properties matching up with fields in the database.
If I have to create POCO classes for every table in the system, there would be 250+ classes that essentially do nothing except package the data and pass it to our data access layer.
Further, it seems as if I need to create an ApiController for basically every table in the database that I want to expose via the Web Api because you only have GET, POST, PUT, DELETE per route? Please help, banging head on desk.
Please see answers below:
1.**Using **"IDictionary of name/value pairs" is fine if your resource supports GET methods only. If you want users to post or update data, how will you validate the data? In addition, if you want to add HATEOAS, how would you do that? In terms of extension, how would you support nested object hierarchy like the one below:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
public IList<PurchaseDetail> PurchaseHistory { get; set; }
}
public class PurchaseDetail
{
public int Id { get; set; }
public DateTime PurchaseDate { get; set; }
public decimal Cost { get; set; }
}
2. You can have more than one GET, POST,etc per resources by defining different routes. More from this link http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

RavenDB Persisting chain of relationships

I'm working on a collaborative document editing tool that's going to use RavenDB for persistence. In my domain I have a document class that looks like this.
public class Document
{
public string Id { get; private set; }
public string Name { get; set; }
public IRevision CurrentRevision {get; private set; }
public string Contents {get { return CurrentRevision.GenerateEditedContent(); }}
}
As you can see that document then has a CurrentRevision property that points to an IRevision object that looks like this.
public interface IRevision
{
IRevision PreviousRevisionAppliedTo { get; }
IRevision NextRevisionApplied { get; set; }
Guid Id { get; }
string GenerateEditedContent();
}
So the basic idea is that the document's contents are generated on the fly by checking out the current revision, which in turn checks it's parent revision, and so on and so forth.
Out of the box, RavenDB doesn't seem to handle persisting this chain of object references the way I need it to. I've been trying to persist it by just calling Session.Store(document), and hoping that the list of associated revisions would get stored as well. I've looked into some pieces of the RavenDB framework like custom serializers, but I can't figure out a clear path that would allow me to deserialize and reserialize the data as I would like. What's a good way to handle this situation.

Splitting Out a Table to Improve Performance

my user's table in the database is becoming increasingly larger (in terms of columns not rows) and as a consequence is slowing down various areas of my site. This is because it tries to grab every column from the user's table everytime it does a join against it.
I figured i would keep all the common fields in the user's table and then put the additional fields in seperate tables. For example, say i have the following tables in my database:
Users:
- UserID (PK, Identity)
- UserName
- Password
...
UsersActivity:
- UserID (PK, FK)
- LastActivityDate
- LastLoginDate
...
UsersPreferences:
- UserID (PK, FK)
- HtmlEmail
- HideEmail
...
With the following entities:
public class User {
public virtual int UserID { get; set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual UserActivity Activity { get; set; }
public virtual UserPreferences Preferences { get; set; }
}
public class UserActivity {
public virtual User User { get; set; }
public virtual DateTime LastActivityDate { get; set; }
public virtual DateTime LastLoginDate { get; set; }
}
public class UserPreferences {
public virtual User User { get; set; }
public virtual bool HtmlEmail { get; set; }
public virtual bool HideEmail { get; set; }
}
I was just wondering what is the best way to map this for optimum performance? I figured i could do a one-to-one mapping on the Activity and Performance properties in the User entity. However as far as i understand one-to-one mapping doesn't support lazy loading and this approach would end up being slower.
I also looked into component mapping and wasn't too sure whether i could map this into a seperate table (please correct me if it would be better to keep it in the same table) and whether components supported lazy loading.
Before i go about doing some heavy refactoring of my application i thought i would get the opinion of someone who might have done this. Really appreciate the help.
Thanks
Edit: I found that you could lazy load a one-to-one relationship as long as it is required/constrained. Which it is my case. Therefore i went ahead and carried out the instructions in the following article:
http://brunoreis.com/tech/fluent-nhibernate-hasone-how-implement-one-to-one-relationship/
The trouble now is that i get the error:
NHibernate.Id.IdentifierGenerationException: NHibernate.Id.IdentifierGenerationException: null id generated for: UserActivity.
In NHibernate 3.0 one-to-one relationship supports lazy loading.
And I think that it is better to use Component with combination of Lazy property. Then you will be able to leave all properties in one table and not load them all at once.
You should do some additional application profiling to determine why you're having a performance problem. It's unlikely that it's due to the number of columns in the select list. You probably have an N+1 select problem.
That said, there are many good reasons to use a lightweight object so you might want to look at implementing a DTO (data transfer object) for this.