server/posts: support note-text search query
This commit is contained in:
parent
1f14f2fc16
commit
0b21d98c9b
4 changed files with 61 additions and 22 deletions
1
API.md
1
API.md
|
@ -710,6 +710,7 @@ data.
|
|||
| `comment-count` | having given number of comments |
|
||||
| `fav-count` | favorited by given number of users |
|
||||
| `note-count` | having given number of annotations |
|
||||
| `note-text` | having given note text (accepts wildcards) |
|
||||
| `relation-count` | having given number of relations |
|
||||
| `feature-count` | having been featured given number of times |
|
||||
| `type` | given type of posts. `<value>` can be either `image`, `animation` (or `animated` or `anim`), `flash` (or `swf`) or `video` (or `webm`). |
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
<td><code>note-count</code></td>
|
||||
<td>having given number of annotations</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>note-text</code></td>
|
||||
<td>having given note text (accepts wildcards)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>relation-count</code></td>
|
||||
<td>having given number of relations</td>
|
||||
|
|
|
@ -69,25 +69,35 @@ def _create_score_filter(score: int) -> Filter:
|
|||
return wrapper
|
||||
|
||||
|
||||
def _create_user_filter() -> Filter:
|
||||
def wrapper(
|
||||
query: SaQuery,
|
||||
criterion: Optional[criteria.BaseCriterion],
|
||||
negated: bool) -> SaQuery:
|
||||
assert criterion
|
||||
if isinstance(criterion, criteria.PlainCriterion) \
|
||||
and not criterion.value:
|
||||
# pylint: disable=singleton-comparison
|
||||
expr = model.Post.user_id == None
|
||||
if negated:
|
||||
expr = ~expr
|
||||
return query.filter(expr)
|
||||
return search_util.create_subquery_filter(
|
||||
model.Post.user_id,
|
||||
model.User.user_id,
|
||||
model.User.name,
|
||||
search_util.create_str_filter)(query, criterion, negated)
|
||||
return wrapper
|
||||
def _user_filter(
|
||||
query: SaQuery,
|
||||
criterion: Optional[criteria.BaseCriterion],
|
||||
negated: bool) -> SaQuery:
|
||||
assert criterion
|
||||
if isinstance(criterion, criteria.PlainCriterion) \
|
||||
and not criterion.value:
|
||||
# pylint: disable=singleton-comparison
|
||||
expr = model.Post.user_id == None
|
||||
if negated:
|
||||
expr = ~expr
|
||||
return query.filter(expr)
|
||||
return search_util.create_subquery_filter(
|
||||
model.Post.user_id,
|
||||
model.User.user_id,
|
||||
model.User.name,
|
||||
search_util.create_str_filter)(query, criterion, negated)
|
||||
|
||||
|
||||
def _note_filter(
|
||||
query: SaQuery,
|
||||
criterion: Optional[criteria.BaseCriterion],
|
||||
negated: bool) -> SaQuery:
|
||||
assert criterion
|
||||
return search_util.create_subquery_filter(
|
||||
model.Post.post_id,
|
||||
model.PostNote.post_id,
|
||||
model.PostNote.text,
|
||||
search_util.create_str_filter)(query, criterion, negated)
|
||||
|
||||
|
||||
class PostSearchConfig(BaseSearchConfig):
|
||||
|
@ -187,7 +197,7 @@ class PostSearchConfig(BaseSearchConfig):
|
|||
|
||||
(
|
||||
['uploader', 'upload', 'submit'],
|
||||
_create_user_filter()
|
||||
_user_filter
|
||||
),
|
||||
|
||||
(
|
||||
|
@ -311,6 +321,11 @@ class PostSearchConfig(BaseSearchConfig):
|
|||
search_util.create_str_filter(
|
||||
model.Post.safety, _safety_transformer)
|
||||
),
|
||||
|
||||
(
|
||||
['note-text'],
|
||||
_note_filter
|
||||
),
|
||||
])
|
||||
|
||||
@property
|
||||
|
|
|
@ -27,8 +27,8 @@ def score_factory(user_factory):
|
|||
|
||||
@pytest.fixture
|
||||
def note_factory():
|
||||
def factory():
|
||||
return model.PostNote(polygon='...', text='...')
|
||||
def factory(text='...'):
|
||||
return model.PostNote(polygon='...', text=text)
|
||||
return factory
|
||||
|
||||
|
||||
|
@ -294,6 +294,25 @@ def test_filter_by_note_count(
|
|||
verify_unpaged(input, expected_post_ids)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('input,expected_post_ids', [
|
||||
('note-text:*', [1, 2, 3]),
|
||||
('note-text:text2', [2]),
|
||||
('note-text:text3*', [3]),
|
||||
('note-text:text3a,text2', [2, 3]),
|
||||
])
|
||||
def test_filter_by_note_count(
|
||||
verify_unpaged, post_factory, note_factory, input, expected_post_ids):
|
||||
post1 = post_factory(id=1)
|
||||
post2 = post_factory(id=2)
|
||||
post3 = post_factory(id=3)
|
||||
post1.notes = [note_factory(text='text1')]
|
||||
post2.notes = [note_factory(text='text2'), note_factory(text='text2')]
|
||||
post3.notes = [note_factory(text='text3a'), note_factory(text='text3b')]
|
||||
db.session.add_all([post1, post2, post3])
|
||||
db.session.flush()
|
||||
verify_unpaged(input, expected_post_ids)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('input,expected_post_ids', [
|
||||
('feature-count:1', [1]),
|
||||
('feature-count:3', [3]),
|
||||
|
|
Loading…
Reference in a new issue