2016-06-06 4 views
0

Каждый документ в моем индексе Elasticsearch имеет два списка управления доступом, содержащие идентификаторы пользователей. Один из них - список разрешений, другой - список запретов. Я пытаюсь добавить фильтр к заданному запросу, который рассматривает эти списки ACL. Я думал, что могу использовать запрос bool с предложением must для данного запроса, предложением filter для списка разрешений и предложением must_not для списка запретов. Что я до сих пор (пример для пользователя 1):Документы запроса с фильтром контроля доступа

{ 
"bool" : { 
"must" : { 
    [given query] 
}, 
"filter" : [ { 
    "match" : { 
    "acl.allow" : { 
     "query" : "/user/1", 
     "type" : "boolean" 
    } 
    } 
}], 
"must_not" : [ { 
    "match" : { 
    "acl.deny" : { 
     "query" : "/user/1", 
     "type" : "boolean" 
    } 
    } 
}] 
} 
} 

К сожалению, этот запрос не возвращает желаемый результат. Он возвращает объекты, которые не указали пользователя 1 в списке разрешений (поведение, которое я не понимаю). Кроме того, он (очевидно) игнорирует объекты с пустым списком управления доступом (который должен быть видимым для всех). Любые предложения по исправлению этого?

+0

Что такое отображение для всего поля 'acl' и, кроме того, просьба предоставить некоторые примеры документов, особенно для полей' acl'. –

ответ

1

Я понял. Прежде всего, использование match на самом деле не является хорошим решением для такого рода запросов - благодаря его анализатору. Использование term, хотя оставило меня озадаченным, почему я не получил никаких результатов. Термины запросов возвращают результаты только в том случае, если соответствующее поле установлено на not_analyzed. Таким образом, я изменил свое отображение:

"acl": { 
     "properties": { 
      "allow": { 
      "type": "string", 
      "index": "not_analyzed" 
      }, 
      "deny": { 
      "type": "string", 
      "index": "not_analyzed" 
      } 
     } 
     } 

Моя вторая проблема обработки объектов с пустыми списками ACL, как видно кто-была решена с помощью exists вложенных в must_not вложен в bool. Это рекомендуется в качестве замены устаревшего запроса missing. Мой последний запрос выглядит так и передал все тесты, связанные с ACL, о которых я мог думать.

{ 
"bool" : { 
"must" : { 
    [given query] 
}, 
"filter" : { 
    "bool" : { 
    "should" : [ { 
     "terms" : { 
     "acl.allow" : [ "/user/1" ] 
     } 
    }, { 
     "bool" : { 
     "must_not" : { 
      "exists" : { 
      "field" : "acl.allow" 
      } 
     } 
     } 
    } ] 
    } 
}, 
"must_not" : { 
    "terms" : { 
    "acl.deny" : [ "/user/1" ] 
    } 
} 
} 
} 
+1

Две вещи: 1. Существует фильтр 'missing', который фактически является таким же, как' must_not', содержащий 'exists'. 2. Это незначительно, но если вы не отправляете массивы в acl-запросы, вы можете изменить его на 'term' и отказаться от использования массива' [] '(поскольку он просто принимает один термин). – pickypg

+1

Спасибо за вход! Я использую API java, где фильтр 'missing' отмечен как устаревший. Вот почему я использую 'bool' /' must_not'/'exists' (как указано в java-документах). Ваше возражение относительно использования массивов на 100% правильное. Однако в моем случае пользователь может принадлежать к одной или нескольким группам, идентификаторы которых отправляются вместе с идентификатором пользователя. Однако это не было раскрыто, так что вы не знали. Я попытался упростить свою проблему. :) – Felix

Смежные вопросы