Developer forum

Forum » Development » Range price facet

Range price facet

Jose Caudevilla
Reply

Hi:

I have to implement a range price facet. This range has to contain the maximun and minimun price of a set of products.

For example , if i have a set of bikes the minimun is 100 and the maximun is 10000.

So if i want to get only the white bikes by a facet the minimun and maximun price must belong to the white bikes set.

Im trying to get this maximun and minimun using a BeforeQuery / AfterQuery but i get a StackOverFlowException in both notifications.

 

Here is the code of the notifications:

 

BeforeQueryNotification

namespace Cemevisa.Notifications
{
    [Dynamicweb.Extensibility.Notifications.Subscribe(Dynamicweb.Indexing.Notifications.Query.BeforeQuery)]
    public class BeforeQueryNotification : Dynamicweb.Extensibility.Notifications.NotificationSubscriber
    {

        public override void OnNotify(string notification, NotificationArgs args)
        {
            Dynamicweb.Indexing.Notifications.Query.BeforeQueryArgs beforeQueryArgs = args as Dynamicweb.Indexing.Notifications.Query.BeforeQueryArgs;

            if (args == null || !(args is Dynamicweb.Indexing.Notifications.Query.BeforeQueryArgs))
                return;

            QueryService queryService = new QueryService();

            
            IQueryResult queryResult = queryService.Query(beforeQueryArgs.Query, beforeQueryArgs.Settings);
            

            base.OnNotify(notification, args);
        }
    }
}

 

 

AfterQueryNotification

namespace Cemevisa.Notifications
{
    [Dynamicweb.Extensibility.Notifications.Subscribe(Dynamicweb.Indexing.Notifications.Query.AfterQuery)]
    public class AfterQueryNotification : Dynamicweb.Extensibility.Notifications.NotificationSubscriber
    {

        public override void OnNotify(string notification, NotificationArgs args)
        {
            Dynamicweb.Indexing.Notifications.Query.AfterQueryArgs afterQueryArgs = args as Dynamicweb.Indexing.Notifications.Query.AfterQueryArgs;

            if (args == null || !(args is Dynamicweb.Indexing.Notifications.Query.AfterQueryArgs))
                return;

            double max = 0.0, min= Double.MaxValue;


            //ejecutar la consulta para obtener los maximos y los minimos
            QueryService queryService = new QueryService();

            IQueryResult queryResult = queryService.Query(afterQueryArgs.Query, afterQueryArgs.Settings);

            IEnumerable<object> resultado = queryService.Query(afterQueryArgs.Query, afterQueryArgs.Settings).QueryResult;

            resultado.Count();

            if(resultado.Count() <= 1000)
            {
                foreach (var products in resultado)
                {
                   //get the maximun and minimun
                }
            }

            base.OnNotify(notification, args);
        }
    }
}

 

Is there another way to do this?

 

Jose, 

Regards.


Replies

 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Jose,

 

How are you planing to render the range facet? In my mind a range can be achieved without any custom coding using manual index fields of type grouping  https://doc.dynamicweb.com/documentation-9/indexing/indexing-search/indexes#4785

 

This is a lot more efficient because it does no additional processing on query time. It basically becomes a new field with a value, behaving like any other facet. This means that you'll get a proper representation of ranges after you filter by "white".

 

Would that solve your issue?

 

Best Regards,

Nuno Aguiar

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
This post has been marked as an answer

Hi Jose,

The reason you're getting a StackOverflowException is because you're invoking QueryService.Query from inside the BeforeQuery. BeforeQuery and AfterQuery are both broadcast from QueryService.Query. That means that your subscriber will call QueryService.Query which will call your subscriber and so on. You need to break the cycle.

However, I don't quite understand why it's needed. Since 9.8.0, Dynamicweb gives you the option of indexing all product prices. In addition, numeric facets now provide minimum and maximum values. You can create a numeric facet on the price that you want to show, and that facet will give you tags for minimum and maximum values that you can use to render however you like.

- Jeppe

EDIT: Fixed mistype of version number from 9.7 to 9.8.

Votes for this answer: 1
 
Jose Caudevilla
Reply

Hi Nuno,

Here is the custom facet that im developing.

The custom facet is render by a jquery library.

This library render a bar so the user can select the price that want to filter.

I know your options is more efficient but i want that the users can select the price by themselves.

 

Thanks,

Jose

 
Jose Caudevilla
Reply

Hi Jepper:

 

My stagging version is 9.7.0.I didn't know that numeric facets provide minimun and maximun values, it will be all that i need to solve my problem.

I couldn´t find how to get this values. How can i get this values please ?

 

Thanks,

 

Jose

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
This post has been marked as an answer

Hi Jose,

I made a mistype in my post. It's available from 9.8, not 9.7. Those two numbers are pretty close on the keyboard ;)

If you upgrade to 9.8, you can create a numeric facet and when rendering the facet, you can use the tags "Facet.MinimumValue" and "Facet.MaximumValue".

- Jeppe

Votes for this answer: 2
 
Nuno Aguiar Dynamicweb Employee
Nuno Aguiar
Reply

Hi Jeppe,

That's a great feature in 9.8. I did not know about it until now :)

 

Hi Jose,

It makes sense if you want to have a slider. Glad you found a simple solution with 9.8

 

BR,

Nuno

 
Lars Larsen
Lars Larsen
Reply

Hi Jeppe

I am using the Product catalog for Viewmodel and would like to get the minimum- and maximumvalues for a range facet. Aren't these properties available in the viewmodel? Can't seem to find them.

 
Lars Larsen
Lars Larsen
Reply

I now see that the numeric facet option values are sorted in FacetViewModel.Options. I therefore just get first and last value in the list as min. and max. values smiley

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
This post has been marked as an answer

Hi Lars,

It seems that these values weren't added to the FacetViewModel by accident.

I'm glad that you found a workaround, but I'll make an internal task to make them available so you don't have to rely on sort order.

- Jeppe

Votes for this answer: 1
 
Kristian Kirkholt Dynamicweb Employee
Kristian Kirkholt
Reply

Hi Lars

The Feature regarding Minimum and maximum values for FacetViewModel has been implemented in Dynamicweb version 9.8.4

This build is available in the download section

https://doc.dynamicweb.com/downloads/releases

Kind Regards
Dynamicweb Support
Kristian Kirkholt

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

We've been experimenting with the MaximumValue and MinimumValue and we do see the proper values. However, it seems to always be the min and max of all products in the index, not on the current result set. Is there an option to get min and max for the current filtered set of products?

Thanks!

Imar

 

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply

Hi Imar,

This should not be the case. Only facet options that actually have hits in the current query result are considered in relation to minimum and maximum values. Do you by any chance have a notification subscriber, or other custom implementation, that filters the results after the index provides the result? It's currently the only thing I can think of that could produce this outcome.

- Jeppe

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Thanks Jeppe. Upon further investigation, it turned out that the numbers were correct after all. However, we had the facet on the product price while the frontend was showing prices from the price matrix, so the min and max values didn't always line up with your expectations. Is there any guidance on what you said above: "Since 9.8.0, Dynamicweb gives you the option of indexing all product prices."? Since there can be many prices in the matrix, for different currencies and such, how would I set up the index and the range filter to get the proper results? (We're building a price range slider in this particular case and thus the min and max are important).

Thanks!

Imar

 
Jeppe Eriksson Agger Dynamicweb Employee
Jeppe Eriksson Agger
Reply
This post has been marked as an answer

Hi Imar,

There are a couple of ways to do that.

  1. Have a set of facets for each context that you want to use and have different Product Catalog paragraphs
  2. Create a facet group with facets for each price field you need. Then make them appear conditionally based on a query parameter

Of the two options, I believe 2) is the more robust one.

Assuming option 2), you could then send a unique context key (maybe "{languageid}_{currency code}") as a query parameter with every search, then have your price facets be shown conditionally based on the value of the context key. This allows you to hide and show facets depending on your context. The query parameter doesn't need to be used in the query. Also, you could split the standard product facets and price facets into different groups and separate the price facets for each context in their own facet groups which could make it easier to work with.

I hope that helps you to proceed. Otherwise, let me know.

- Jeppe

Votes for this answer: 1
 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Thanks, Jeppe. That's very helpful. The ball is in the customer's court for now but this will come in handy soon!

 
Ivan Marijanović
Ivan Marijanović
Reply

Hi Nuno

I am tryingto implement Price Range facet but link you shared in this response is no longer availble. 

Ivan

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Maybe this helps? https://doc.dynamicweb.com/documentation-9/how-tos/general/implementing-a-pricerange-query

 

You must be logged in to post in the forum