how to filter search by values that are not available
Asked Answered
H

5

12

I have a list of items as:

i = SearchQuerySet().models(Item)

now, each item in i has a attribute, price

I want to narrow the result in which price information is not available along with the ones falling in a given range

something like

i.narrow('price:( None OR [300 TO 400 ] )')

how can that be done?

Halsted answered 11/6, 2013 at 12:55 Comment(2)
I wonder if this syntax might work?Respective
@MartijnPieters that syntax worked separately, but not along with OR. I have updated my questionHalsted
F
13

Try this:

-(-price:[300 TO 400] AND price:[* TO *])

is logically the same and it works in Solr.

Flight answered 20/6, 2013 at 10:50 Comment(2)
why ~AND` not OR though it works for both AND and OR, i wonder whyHalsted
I don't think it work with OR. have a look at this link: whatis.techtarget.com/definition/…. If you forget for a second the negative inside the parentesys what we are actualy doing here in a NAND between 2 term and that can be quite similar to a OR but not in all cases, be careful.Flight
A
6

As per the SolrQuerySyntax

Pure Negative Queries:

-field:[* TO *] finds all documents without a value for field

You can try:

q=(*:* -price:[* TO *]) OR price:[300 TO 400]

Analgesic answered 11/6, 2013 at 13:17 Comment(8)
it still is not giving me items with prices between 300 to 400Halsted
whats the field type of prices ? sint ?? or string/text ?Analgesic
price field is decimal (float)Halsted
how does your query look now ? can you update your question ?Analgesic
i dont understand. I want price falling in a particular range and the ones with None values. i dont know the query for thatHalsted
update the answer with the query. This is tested and works fine.Analgesic
can you please give me how to write inside .narrowHalsted
Not sure of that. you can paste as is in the narrow without the q= part.Analgesic
M
0

The aim was to sort some items by score based on an boosting by type and plus if a type:bike item has an image. The result should be:

  1. Cars
  2. Boats
  3. Bikes with an image
  4. Bikes without an image

This was my first query approach: type:"car"^10000 OR type:"boat"^5000 OR (type:"bike" AND image-type:[* TO *])^100 OR type:"bike"^5 (works fine)

But i forgot old data items without the type field. The should be in the result set like this:

  1. Cars
  2. Boats
  3. Bikes with an image
  4. Bikes without an image
  5. All items without a type

So i changed my query to -type:[* TO *] OR type:"car"^10000 OR type:"boat"^5000 OR (type:"bike" AND image-type:[* TO *])^100 OR type:"bike"^5 and ended up with no results.

So i found this thread and tried to change my query to -(type:[* TO *] OR -type:"car"^10000 OR -type:"boat"^5000 OR -(type:"bike" AND image-type:[* TO *])^100 OR -type:"bike"^5) like shown in this answer https://mcmap.net/q/927597/-how-to-filter-search-by-values-that-are-not-available

But sadly all items have the same score :(

Mannie answered 8/11, 2016 at 14:22 Comment(0)
M
0

The double negated query suggested by Maurizio may cause error:

unexpected docvalues type NUMERIC for field 'price' (expected one of [SORTED, SORTED_SET]). Re-index with correct docvalues type.

(Even after re-indexing. This may have something to do with the index and store and docvalues settings of the field.)

What you could do instead is exempt both ranges (before and after) of the values you are actually interested in:

-(price:[* TO 300} price:{400 TO *])

Note that values 300 and 400 are excluded by using curly brackets in this negated query and are thus included in the search results.

Marrilee answered 30/10, 2017 at 6:49 Comment(0)
B
-1

One can use a filter query if you do not care about the document score and want to leverage the filter cache, like:

?q=*:*&fq=((-price:[* TO *]) or (price:[300 TO 400]))
Biles answered 19/6, 2013 at 7:57 Comment(2)
Cojucaru, Can you give the query in models(Item).filter .. form. I am realyy new to solr and am not able to convert your code into that formHalsted
try something like this models(Item).filter_or(price=None, price__range=[300, 400]) based on github.com/soby/django-haystack/commit/… for Empty values one needs to use NoneBiles

© 2022 - 2024 — McMap. All rights reserved.