Request one document or another depending on the specific field
Imagine a SolR index with documents like this
[
{
ProductId: 123,
Contract: abc
},
{
ProductId: 123,
Contract: def
},
{
ProductId: 123
},
{
ProductId: 567
},
{
ProductId: 567,
Contract: bar
}
]
- There is always a document with a specific ProductId and without
Contract
- In addition, there can be from 0 to n documents with
Contract
I need a query where I can use Contract
, and it should return me everything, ProductId
either the one that has the given one Contract
, if it exists, or the only document without it Contract
at all.
For example, I will make a request with Contract: def
(somehow) and it should give me this
[
{
ProductId: 123,
Contract: def
},
{
ProductId: 567
}
]
- Document with is
Contract:abc
not part of the result - Document with
ProductId:123
but without isContract
not part of the result - The document
ProductId:567
is part of the result, because there is no document with theseProductId
andContractId: def
In other words, I need something like
- Give me one document per
ProductId
andContract:X
XOR-Contract*
, but not both.
source to share
Step 1 Write your request to return reports without Contracts, as well as all with matching contracts, but those with a matching contract have the highest score. This eliminates the problem for which you sometimes need the items in the results, which do not correspond to the Contract value: q=Contract:"def" OR (*:* -Contract:[* TO *])
. (*:* -Contract:[* TO *])
matches all records without contracts, but Contract:"def"
matches records with the correct contract. Entries that match Contract:"def"
naturally have a higher score than those without a contract, but if there are any problems or you just want to be sure, you can add a promotion to this offer Contract:"def"^2
.
Step 2 Add the Grouping Results to the query, configured so that you only ask for the highest score for any given ProductId
:
q=Contract:"def" OR (*:* -Contract:[* TO *])&group=true&group.field=ProductId
This requires the field to ProductId
be configured in your schema.xml
as multiValued="false"
, since multi-value fields cannot be used as groups. I also assume that you are using the Standard Query Parser , either the default one in yours solrconfig.xml
, or by adding an argument defType=lucene
when making the query.
The results should look something like this:
'grouped'=>{
'ProductId'=>{
'matches'=>5,
'groups'=>[{
'groupValue'=>123,
'doclist'=>{'numFound'=>3,'start'=>0,'docs'=>[
{
'ProductId'=>123,
'Contract'=>'def'}]
}},
{
'groupValue'=>567,
'doclist'=>{'numFound'=>2,'start'=>0,'docs'=>[
{
'ProductId'=>567}]
}}]}}}
Note that neither the values matches
nor the values numFound
in the result set tell you how many groups were returned, but the argument rows=XX
can be used to determine the maximum number of groups you want (in this case ProductIds).
source to share