If you’ve added the stock to the ProductDocument you can just add a sorting for in BuildSortings(...). By having it first in the additional sortings it would push unavailable items to the end.
Don’t store de actual quantity in search index, instead have a calculated property (of field on the product) that contains if they are in stock as in the example above.
Sorting on “In stock” may break other sorting operations, example hits by score for free text search that in the most cases need to be the first sort field.
I was thinking I’d add a boolean to the productdocument depending on whether or not there is a instockquantity > 0 on any of the variants and then use Nils’ example sort. That would work, right?
I’m almost done with the above. I’ll try it and see how free text search behaves.
Could you give an example in code for option 3? I can’t get it to work, all items that are not in stock are excluded from the result, using the following code:
This also results in products that are not in stock to be excluded from the result.
I’m doing this in the BuildQuery-method in ProductSearchServiceDecorator.
I’ve tried with both exists and just match the value to “true”, both filters out all out of stock products. When I used exists I only set the value if the product had stock.
I also tried boosting more than 1, such as 100 or 20, without any change. I’m lost here…
This is the property in ProductDocument, no attributes: public Dictionary<string, bool> InStock { get; set; }
The documentation on Exists suggests that it will only retrieve documents that has a value for that field in the index, so if you leave it out when it’s not in stock it makes sense that you’re not seeing it.
Could you maybe add a weight to documents where the InStock property is true?
var countryId = _requestModelAccessor.RequestModel.CountryModel.Country.Id;
allQueries.Add(qc.FunctionScore(fs => fs
.Functions(fu => fu
.Weight(w => w
.Weight(100)
.Filter(wf => wf
.Term(t => t.InStock[countryId], true))))));