Elastic Search, Nest. functional sorting - nest

I'm building a filter page, with facets etc, which works as it should.
Now the our customer has a request to, basically "Be able to decide which sorting the items comes out in".
Each product is decorated with a Product Display Order, and is in a Product Line.
We got these example Product Display Orders:
1. Featured Item
2. Core Item
3. Spare Part
4. Utility
And these Product Lines:
1. Hammers
2. Saw
3. Wood
and the sorting is like this:
Sorting should firstly be based on Product Display Orders, secondly by product lines, thirdly Alphabetically.
So all products which is a Featured Item is listed first, and all these Featured Items is then sorted by their product line, and if some product are in the same Featured Item and Product Line, then its alphabetically.
The challenge is: I can't just get the sorting of Product Display order items and product lines as a number on the product, i only got a name/id.
We've thought of Boosting based on if the product are in the different categories, but it seems a bit messy.
OR
See if it possible to have some logic in the Sorting.
Sort by productDisplayOrder:
1. featured, 2. core Item ...
Then by ProductLines:
1. Hammers, 2. Saw ...
Then by Name DESC.
Which way is the best way to have this sorting, is it possible to give this logic to elastic, if it is a match and then sort it. Or are we needed to twist the boosts of product?
Hopefully this makes sense for you.
Thanks in advance! :)

Option 1). Quickest/Best performing solution would be to create new/separate integer fields for productDisplayOrder and ProductLine and then use those in your sort criteria as described (after reindexing and validating the the data is indexed as expected).
Option 2) If you want more nuance than described (eg higher scoring matches can 'break through' the ordering ceiling described) then you can explore using a Function Score Query to implement a custom scoring strategy that takes productDisplayOrder and ProductLine into consideration in generating an overall match score.
Option 3). If you can't change the mapping and reindexing your data, you can use Script-Based Sorting to generate sorting values from the currently indexed productDisplayOrder/ProductLine text using a script (eg Groovy). Keep in mind that query performance will be worse than the first two options.

Related

How to get distinct xp values?

Each product has two xp parameters - productLine, productType.
Under productLine, there are multiple product types.
I need to fetch list of distinct productType under each productLine.
There is limit on listing all products due to pagination.
Is it possible with ordercloud?
The short answer is there's no shortcut way to do this. Typically in these scenarios it works the other way - you have a pre-defined list of possible values and restrict what goes in via a dropdown list in the UI, or an enum in the integration layer, or something along those lines. For your scenario, you would need to resort to fetching all products (page by page) and keeping track of those unique values. Ideally that one be a one-time thing and going forward I'd suggest validating/restricting the input, although I don't know your exact requirements.

Shopify - auto-tagging by 'compare at price' difference

The shopify store I edit has a 'sale' collection. This consists of products which have been auto-tagged on the condition that the 'compare at price' is higher than the actual price.
I want to create a new 'clearance' section, which would consist of products where the actual price is cheaper than the compare at price by 50% or greater. I can't find a simple way to do this (i.e. by using the inbuilt collection creator).
Can anyone help me out?
Discounts are applied at the checkout, not when browsing a product. That is why the Smart Collection logic has no conditions based on discounts. If I were you I would try and work out how to build a collection "clearance" with conditions that make sense, and then you could create a price rule/discount that would apply to that collection (50% off). It seems like that is the way to go.

Searching products using details.name and details.value using the Best Buy API

The Best Buy Search allows to search products specifying a criterion on details.name and details.value fields.
http://api.remix.bestbuy.com/v1/products(details.name="Processor Speed" & details.value="2.4Ghz")?apiKey=YOURKEY
However details is a collection. The query above actually returns all products has a detail entry named "processor" and a detail entry whose value is "2.4Ghz" but not necessarily in the same details entry. Is there a way to create a query that will return only products for which those value and name are for the same details entry ?
Unfortunately there is no way to do this unless the particular detail you are interested in has been exposed as a top level attribute (processor speed has not). To accomplish this you will need to run your query as you have described, and then comb through the results and remove the irrelevant products in your own code.

Secondary sorting in Magento

I have come across a problem which my developer says there is no solution to.
I have an ecommerce site www.lovefashion.pk roughly 800 products to date. It has categories with collections of products from a particular brand and New Arrivals and Sale pages that show a number of categories. The issue I am faced with is the way Magento displays these products on catalog pages.
We create a custom sort 'BY date' and called it 'Latest' so I would choose a date for a collection and the catalog pages would show the collection with newest sort by date first and so on. Issue is with secondary sorting now. I have products with design codes say Brand A code 1-A, Brand A code 1-B, Brand A code 2-A and so on. When creating these products, we go alphabetically like 1-A,1-B, 2-A etc.
Say a collection has 15 products and i have given all its products a sort by date of 15th April. Magento does the date sorting OK but secondary sorting i.e by product ID (oldest to newest) is what we cant find a way to implement. It shows products now with latest ID first, i.e 20-B, 20-A, 19-B, and so on till 1-A e.g http://www.lovefashion.pk/shop-by-price/
Is there a way to solve this problem? or can SQL manipulation do the trick? Will aprreicate any help
This is a very interesting question. Can you tell us a little more about what you are trying to do? I think you want the products on each page reversed, but the pages to keep the order they have, yes? or do you want the page to go 'Asim Jofa Luxury Lawn Collection 2014 / 1-A' then 'Orient Lawn Kurti Collection 2014 / 01-B' then 'Orient Lawn Kurti Collection 2014 / 01-A' and so on?
Anyway, I think all you need to do is code a secondary sorting of the collection for each page which could be coded in the list.phtml file.
Psuedo code:
get the collection sorted by date and paginated
reverse the collection
pass the collection into the existing foreach(){echo(<li>product info</li>)}
So 'reverse the collection' might be tricky. And strictly you want to sort by sku on 1A, 1B, 2A, 2B - but I'm sure your developer can figure it out.
$reversed_collection = array_reverse($current_page_collection->toArray());
might work but I think the toArray will loose all the class types so it's not the same as reversing the object.
Collections are like arrays so end($current_page_collection) and prev($current_page_collection) might work but you would have to try it (and report back if it works). In that case a simple for loop to iterate over each item of the colection.
If you are making a custom filter then really it is just a case of putting each item of the collection into an array with an appropriate key and sorting with ksort().
So it is my opinion that it can be sorted that way, but it should be done in two stages.

Lucene.Net: How to grab the next 10 results after a document that has a certain field value?

Suppose I have a query in Lucene.Net 3.0.3 that matches 1,000,000 documents, and each document has a field named ProductID with a unique value. How can I grab the next 10 items immediately after a specific ProductID?
For instance, grab me the next 10 items after ProductID 4264423.
The ProductID could be anywhere within the 1,000,000 matches, and sorted however I wish.
One brute force solution is to loop through all the ScoreDocs, and use the FieldCache to find the correct ProductID, then grab the next 10. However, that seems inefficient, since we'd need to populate a huge ScoreDocs array.
Another idea is to use a custom Collector, along with FieldCache to look for the correct ProductID, but as far as I know, Collector's aren't sorted.
Perhaps a solution is to use a combination of a custom Collector with a PriorityQueue, use the FieldCache to find the correct ProductID, note the Score of that document, then grab the next 10 items based on Score. (Although, if there are similar Score values, how is that handled?)
Please provide code samples, as I'm a Lucene.Net newbie. (Sample code preferably in C#.)
If a custom Collector + PriorityQueue is a viable option, here is some sample code to assist: https://stackoverflow.com/a/7938433/1145177