solr search query apply condition in both field (exist OR does not exist) - solr

I have data with different dynamic field. i want to apply the condition in exists field record and i need not exists field records also. My Solr version 6.1.0
{"employeeid" : "220", "displayname_s": "abu", "attr_36977": 55 },
{"employeeid" : "910", "displayname_s": "test","attr_36400": 565 },
{"employeeid" : "210", "displayname_s": "sam"},
{"employeeid" : "64", "displayname_s": "wel", "attr_36977": 152},
i write a query like this
(-attrl_36977:[* TO *] OR attrl_36977:[0 TO 100])
but this query not workout.
the idle result is first three records(220,910,210). how to solve the requirement

You have to be explicit about what you're subtracting the first part of your OR statement from:
(*:* -attrl_36977:[* TO *]) OR attrl_36977:[0 TO 100]
.. will give you any documents that doesn't have a value in attrl_36977 or a value between 0 and 100 inclusive.

Related

Solr faceting on a Query Function result

Is it possible to produce solr facets for a field which is the result of Query Function?
I have an index of products with a price field for each store they are available in:
{
"id" : "p1",
"name_s" : "Product 1",
"description_s" : "The first product",
"price_l1_d" : 19.99,
"price_l2_d" : 20.00,
"price_l3_d" : 20.99,
"price_l4_d" : 19.99,
"price_l5_d" : 25.00,
"price_l6_d" : 18.00
},
{
"id" : "p2",
"name_s" : "Product 2",
"description_s" : "The second product",
"price_l1_d" : 12.99,
"price_l2_d" : 15.00,
"price_l3_d" : 13.49,
"price_l4_d" : 14.00,
"price_l5_d" : 12.50,
"price_l6_d" : 16.00
}
and I need my query to return the cheapest price in the customer's 3 closest stores.
I know I can return this value using fl=min(price_l2_d, price_l4_d, price_l6_d) and I can even sort on this but is it possible to return a "Price" facet based on this value for each document? Ideally I'd like to be able to show all products whose minimum price (in my 3 stores) is between 0-5, 5-10, 10-15, 15-20 etc etc and filter on this.
I've tried using min(price_l2_d, price_l4_d, price_l6_d) as facet.field but I receive an undefined field error. Is there a better way?
I cannot produce this value at index time because the closest 3 stores could be any combination of three price fields (in this example there is 6 but thee are likely to be over 200)
While not THE solution, I have found A solution which should work. Unfortunately it's not possible to create a traditional facet for price ranges as you would with a single integer attribute, but a two-point slider is possible.
Using the JSON facet API (as suggested by a comment on the original question) and the following:
{
"max" : "max(min(price_l2_d, price_l4_d, price_l6_d))",
"min" : "min(min(price_l2_d, price_l4_d, price_l6_d))"
}
I can return the boundaries of the slider with the smallest minimum price at the three stores and the biggest minimum price.
The values on this slider can then be applied using the {!frange} function as follows:
fq={!frange l=0 u=20}min(price_l2_d, price_l4_d, price_l6_d)
where l is the lower bound and u is the upper bound
Hopefully this helps anyone else looking for an answer to this.

Connecting multiple Filter Queries (fq) in Apache Solr

Let's assume, I have the following documents in my index:
title: Entry #1
myfield: 5
---
title: Entry #2
myfield: 2
---
title: Entry #3
As you can see, myfield is optional and not present in all documents.
Now I want to select all documents where myfield is greater than 3 or the field does not exist. Of course there is also a search word let's say entry, so it finds all documents.
So the query should return Entry #1 and Entry #3.
Currently I am querying like this:
q=entry
defType=dismax
qf=title
fl=*
fq=-myfield:* myfield:[3 TO *]
which does not return any documents. Each filter query alone, so -myfield:* and myfield:[3 TO *] are working like expected.
How can I connect these two filter queries?
It's usually helpful to think of each term of the query as a set of documents, and the boolean operators as operations performed between these sets (i.e. AND finds the intersection between two sets, while OR finds the union). A negative set would then be the difference between sets.
When you use a negative match, you have to subtract it from something. When you don't have any other clauses in your query, Solr helpfully appends the complete set of documents (*:*) in front of your query. But as soon as you add a second boolean term, Solr can't do that any longer - since it doesn't know what you actually mean with your query.
So your negative clause needs to start with a set that the other set (i.e. the documents that doesn't have field) can be subtracted from:
fq=(*:* -myfield:*) OR myfield:[3 TO *]

SOLR: Need to perform a filter query for documents with a field value and documents with out the field itself

I need to filter for documents that have a specific value for a field and all documents which do not have the field :
fq":"((state:"CA") OR NOT(state:*))"
when I execute each subcomponent separately it gives results however when I execute them together I am getting 0 documents found.
You have to subtract the NOT from something.
fq=state:CA OR (*:* NOT state:[* TO *])
So either it's in the set denoted by state:CA, or it's in the set denoted by all documents, minus those that have a value in the field. You can't just say "minus those that have a value in the field", since there is nothing to subtract from (small nitpick: Solr automagically adds the whole set to purely negative queries, so q=-state:[* TO *] would work - but not when you add the boolean operators).

Solr facet query filtering

I'm trying to build a facet query on the manufacturer field when the search term = "LENS" but want to eliminate all those manufactures where there is no lens..
For example:- I need the following output but want to eliminate "Kodak" since there is not lens from that manufacturer....
"facet_fields": {
"manu" : [
"Canon USA": 25,
"Olympus": 21,
"Sony": 12,
"Panasonic": 9,
"Nikon": 4,
"Kodak":0
],
http://localhost/solr/collection1/select?q=lens&rows=0&wt=json&indent=true&facet=true&facet.query=lens&facet.field=manu
does not yield the correct result
You can use facet.mincount to only retrieve facet keys that have a value above a certain treshold. This is 0 by default.
facet.mincount=1
You can also supply the value on a per-field basis if you're doing multiple facets in a single request, f.manu.facet.mincount=1.
Additionally, there should be no need to do a facet.query when you're already performing the same query as the actual query. The facet.query is useful if you want to do arbitrary queries for a facet, within the same document set already returned by your query.

Treat two facets as the same value

Assume a list of books with an Author field. How might one facet on the Author field, but treat the values "Stephen King" and "Richard Bachman" as the same? So that these results:
Hemmingway: 8
Stephen King: 10
Edgar Allan Poe: 20
Richard Bachman: 5
Would be displayed as:
Hemmingway: 8
Stephen King: 15
Edgar Allan Poe: 20
Note that it is unimportant if the facet title is "Stephen King", "Richard Bachman", or something else. It is only important that they are faceted together.
Note that a query-time solution is needed. Unfortunately the schema cannot be changed for this index, it is a general-purpose index and if every user could make his own schema 'tweak' it would get out of hand.
You can achieve that by combining facet fields with facet queries.
Add these to your query:
&facet=true
&facet.field=author
&facet.query=author:("Hemmingway" OR "Stephen King")
Facets returned will look like this:
facet_counts: {
facet_queries: {
"author:("Hemmingway" OR "Stephen King")" : 18
}
facet_fields: {
author: {
"Hemmingway" : 8,
"Stephen King" : 10,
"Edgar Allan Poe" : 20,
"Richard Bachman" : 5
}
}
}
You can also add an 'alias' to the facet query. Change this
&facet.query=author:("Hemmingway" OR "Stephen King")
To
&facet.query={!ex=dt key="Hemmingway"}author:("Hemmingway" OR "Stephen King")
And the facet query output will be:
facet_queries: {
"Hemmingway" : 18
}
I'm not sure if you can merge both output fields (facet_queries and facet_fields) from Solr, but doing that from any client should be straight-forward.
You need an analysis chain that converts the strings. I think SynonymFilter will do this for you if you apply it at index time and at query time. You would need to make sure the sysnonym mapping goes one way only.
I assume you do not need the whole list of facets, just top n authors. If this is the case you can do it in a post processing step.
You know your synonyms and if you put a slightly higher facet.limit(let's say 2*n) then you just have to filter out the synonyms from the result set. If you end up with < n results then just repeat the previous step(worse case you have to do one more request(s) depending on the number of synonyms).
in ex ...&facet=true&facet.field=author&facet.limit=100&facet.mincount=1
This one has nothing to do with Solr, but considering all the restrictions it might just cut it.
Best regards,

Resources