简体   繁体   中英

Solr FilterQuery - using AND and NOT in a query

A document in solr cloud is like

{
 currentcompany : ACME; //text_general
 previouscompanies : Infosys, Hexaware; // text_general multivalued
 post: some string here //text_general probably irrelevant but could be 
       used to replicate my schema. this is the default field
}

When passing a query like

{

 q = *:*;
 fq = {!cache=false}((currentcompany:((ACME OR HDFC OR ICICI) 
      AND (!AIRTEL))) OR (previouscompanies:((LCMS OR HEXAWARE) AND (!LOMBARD))));

 }

I am getting empty result. Can someone help me understand why this is so.

More Info:

df : post //Default field. It is a text_general. when passing either of these, I'm getting the result:

{

 q = *:*;
 fq = {!cache=false}((currentcompany:((ACME OR HDFC OR ICICI) 
      AND (!AIRTEL))) OR (previouscompanies:((LCMS OR HEXAWARE))));

} //removed  AND (!LOMBARD)


{

 q = *:*;
 fq = {!cache=false}((currentcompany:((ACME OR HDFC OR ICICI)
      OR (previouscompanies:((LCMS OR HEXAWARE) AND (!LOMBARD))));

} //removed AND (!AIRTEL)))

EDIT: Sorry. The fields are current company & previous companies.

Update: The following query works

{!cache=false}((currentcompany:((ACME OR HDFC OR ICICI) 
              AND !(AIRTEL))) OR (previouscompanies:((LCMS OR HEXAWARE) 
              AND !(LOMBARD)))); //Used the not operator outside the bracket

Solves my problem, but still curious why the previous format didn't work.

QueryParser is edismax.

Lets talk about your the first part of your correct query:

(currentcompany:((ACME OR HDFC OR ICICI) AND !(AIRTEL)))

Here the idea is to select all the documents that have currentcompany in ACME , HDFC , ICICI but not AIRTEL .

There is no need to specify the not AIRTEL part, you have already specified the list of allowed values (which incidentally does not comprise AIRTEL ).

Now I have to do an important premise, when you use the AND operator in a Solr filter query is like to select the intersection between two groups of documents.

So again, lets try to take only the first part of the wrong query:

(currentcompany:((ACME OR HDFC OR ICICI) AND (!AIRTEL)))

Here you're trying to intersect two sets, the former is the set of documents where currentcompany is in ACME , HDFC , ICICI and the latter is an empty set.

The intersection between a set and an empty set always returns an empty set, that's why Solr does not return any document.

When you use the NOT operator within the brackets you have an empty set, this because

Solr only checks to see if the top level query is a pure negative query

https://wiki.apache.org/solr/NegativeQueryProblems

So you cannot use the NOT operator in side the brackets in this way, you should try with (*:* AND NOT AIRTEL) , this sets is not empty and selects all the documents that not have currentcompany equals to AIRTEL . But as said, this make no sense, because you've already selected the list of allowed currentcompany .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM