[ 
https://issues.apache.org/jira/browse/SOLR-12673?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16586377#comment-16586377
 ] 

Varun Thacker edited comment on SOLR-12673 at 8/20/18 7:13 PM:
---------------------------------------------------------------

Thanks everyone for the tips!

Here's a index
{code:java}
[
{"id" : "1", "users_ss" : ["user1"], "count_i" : 1},
{"id" : "2", "users_ss" : ["user4"], "count_i" : 1},
{"id" : "3", "users_ss" : ["user1", "user2"], "count_i" : 2},
{"id" : "4", "users_ss" : ["user1", "user2", "user3"], "count_i" : 3},
{"id" : "5", "users_ss" : ["user1", "user2", "user3", "user4"], "count_i" : 4}
]{code}
Query : If the document has any user apart from user1, user2 don't show it.
 Results : id:1, id:3

This is what I tried so far :
 Mikhail, here is the frange query . Here's the query I fired
{code:java}
q=*:*&fq={!frange cache=false l=0 
incl=true}sub(sum(query($bq1),query($bq2)),count_i)&bq1=users_ss:user1^=1&bq2=users_ss:user2^=1{code}
This however gives me only document 3 . We don't get document1 because of 
[http://lucene.apache.org/core/7_4_0/queries/org/apache/lucene/queries/function/valuesource/MultiFunction.html#allExists-int-org.apache.lucene.queries.function.FunctionValues:A-]

 

EDIT: Change func to frange to filter out score=0 documents 

Here's another approach I tried with a solution Hoss has proposed 
{code:java}
q={!frange 
u=1}eq(count_i,sum(termfreq(users_ss,"user1"),termfreq(users_ss,"user2"))){code}
This seems to be doing the job
{code:java}
{
  "responseHeader":{
    "zkConnected":true,
    "status":0,
    "QTime":7,
    "params":{
      "q":"*:*",
      
"fl":"id,sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\")),count_i,score",
      "fq":"{!frange 
l=1}eq(count_i,sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\")))",
      "_":"1534788187996"}},
  "response":{"numFound":2,"start":0,"maxScore":1.0,"docs":[
      {
        "id":"1",
        "count_i":1,
        "sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))":1.0,
        "score":1.0},
      {
        "id":"3",
        "count_i":2,
        "sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))":2.0,
        "score":1.0}]
  }} 
{code}
 

So looks like solutions do exist : My question would be is it worth writing a 
specialized query and would it be more efficient than these solutions ?


was (Author: varunthacker):
Thanks everyone for the tips!


Here's a index
{code:java}
[
{"id" : "1", "users_ss" : ["user1"], "count_i" : 1},
{"id" : "2", "users_ss" : ["user4"], "count_i" : 1},
{"id" : "3", "users_ss" : ["user1", "user2"], "count_i" : 2},
{"id" : "4", "users_ss" : ["user1", "user2", "user3"], "count_i" : 3},
{"id" : "5", "users_ss" : ["user1", "user2", "user3", "user4"], "count_i" : 4}
]{code}
Query : If the document has any user apart from user1, user2 don't show it.
Results : id:1, id:3

This is what I tried so far :
Mikhail, here is the frange query . Here's the query I fired
{code:java}
q=*:*&fq={!frange cache=false l=0 
incl=true}sub(sum(query($bq1),query($bq2)),count_i)&bq1=users_ss:user1^=1&bq2=users_ss:user2^=1{code}
This however gives me only document 3 . We don't get document1 because of 
[http://lucene.apache.org/core/7_4_0/queries/org/apache/lucene/queries/function/valuesource/MultiFunction.html#allExists-int-org.apache.lucene.queries.function.FunctionValues:A-]

 

Here's another approach I tried with a solution Hoss has proposed 
{code:java}
q={!func}eq(count_i,sum(termfreq(users_ss,"user1"),termfreq(users_ss,"user2"))){code}
This seems to be doing the job , but I still get documents with score = 0
{code:java}
{
"responseHeader": {
"zkConnected": true,
"status": 0,
"QTime": 6,
"params": {
"q": 
"{!func}eq(count_i,sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\")))",
"fl": 
"id,sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\")),count_i,score",
"_": "1534788187996"
}
},
"response": {
"numFound": 5,
"start": 0,
"maxScore": 1.0,
"docs": [{
"id": "1",
"count_i": 1,
"sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))": 1.0,
"score": 1.0
},
{
"id": "3",
"count_i": 2,
"sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))": 2.0,
"score": 1.0
},
{
"id": "4",
"count_i": 3,
"sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))": 2.0,
"score": 0.0
},
{
"id": "2",
"count_i": 1,
"sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))": 0.0,
"score": 0.0
},
{
"id": "5",
"count_i": 4,
"sum(termfreq(users_ss,\"user1\"),termfreq(users_ss,\"user2\"))": 2.0,
"score": 0.0
}
]
}
}{code}
 

So looks like solutions do exist : My question would be is it worth writing a 
specialized query and would it be more efficient than these solutions ?

> Superset Query
> --------------
>
>                 Key: SOLR-12673
>                 URL: https://issues.apache.org/jira/browse/SOLR-12673
>             Project: Solr
>          Issue Type: New Feature
>      Security Level: Public(Default Security Level. Issues are Public) 
>            Reporter: Varun Thacker
>            Priority: Major
>
> Here's the use-case I am trying to solve for document level access control.
> Documents :
> {code:java}
> [
>   {"id" : "1", "users" : ["user1"]},
>   {"id" : "2", "users" : ["user4"]},
>   {"id" : "3", "users" : ["user1", "user2"]},
>   {"id" : "4", "users" : ["user1", "user2", "user3"]},
>   {"id" : "5", "users" : ["user1", "user2", "user3", "user4"]}
> ]{code}
>  
> Query : If the document has any user apart from user1, user2 or user3 don't 
> show it.
> Results : id:1, id:3, id:4
> Query : If the document has any user apart from user1, user2 don't show it.
> Results : id:1, id:3
> I'm thinking this can be solved by writing a post-filter
> Syntax:
> {code:java}
> {!union_has_all field=users}user1,user2,user3{code}
> The post filter would get each document at a time and see if there is a user 
> in that document that is not part of the query.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to