Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solr, multivalued field: how can I return documents where ALL values in the field are contained within a set?

Tags:

solr

For example, if I have these 2 Documents:

id: 1
multifield: 2, 5

id: 2
multifield: 2, 5, 9

Then say I have a set that I'm querying with, which is {2, 5, 7}. What I would want is document 1 returned because 2 and 5 are both contained in the set. But document 2 should not be returned because 9 is not in the set.

Both the multivalued field and my set are of arbitrary length. Hopefully that makes sense.

like image 623
brian519 Avatar asked Nov 09 '11 19:11

brian519


1 Answers

Figured this out. This was the inspiration, specifically the answer suggesting to use Function Queries.

Using the same data in the question, I will add a calculated field to my documents which contains the number of values in my multivalued field.

id: 1
multifield: 2, 5
nummultifield: 2

id: 2
multifield: 2, 5, 9
nummultifield: 3

Then I'll use an frange with some function queries. For each item in my set, I'll use the termfreq function which will return 1 or 0. I will then sum up all of these values. Finally, if that sum equals the calculated field nummultifield, then I know that for that document, every value in the document is present in the set. Remember my set is 2,5,7 so my function query will look something like this:

fq={!frange l=0 u=0}sub( nummultifield, sum( termfreq(multifield,2), termfreq(multifield,5), termfreq(multifield,7)))

If we fill in the values for Document 1 and 2, it will look like this:

Document 1:  sub( 2, sum( 1,1,0 ) ) = 0  ' in my range of {0,0} so Doc 1 is returned
Document 2:  sub( 3, sum( 1,1,0 ) ) = 1  ' not in the range of {0,0} so not returned

I've tested it out and it works great. You need to make sure you don't duplicate any values in multifield or you'll get weird results. Incidentally, this trick of using frange could be used whenever you want to fake a boolean result from one or more function queries.

like image 134
brian519 Avatar answered Sep 18 '22 19:09

brian519