Commit 42cbda0c authored by Randall Leeds's avatar Randall Leeds

Merge pull request #1282 from hypothesis/searchable_uri-2

Update uri mapping, use match query
parents 9b87cd8e 012d9cfa
...@@ -42,8 +42,8 @@ class Displayer ...@@ -42,8 +42,8 @@ class Displayer
streamfilter streamfilter
.setPastDataNone() .setPastDataNone()
.setMatchPolicyIncludeAny() .setMatchPolicyIncludeAny()
.addClausesParse('references:^' + $scope.annotation.id) .addClause('references', 'first_of', $scope.annotation.id, true)
.addClausesParse('id:=' + $scope.annotation.id) .addClause('id', 'equals', $scope.annotation.id, true)
.getFilter() .getFilter()
$scope.change_annotation_content = (id, new_annotation) => $scope.change_annotation_content = (id, new_annotation) =>
......
class ClauseParser
filter_fields : ['references', 'text', 'user', 'uri', 'id', 'tags', 'created', 'updated']
operators: [
'#<=', '#>=', '#<', '#>', '#=',
'=>', '>=', '<=', '=<', '>', '<',
'[', '=~', '^', '{',
'='
]
operator_mapping:
'=': 'equals'
'>': 'gt'
'<': 'lt'
'=>': 'ge'
'>=': 'ge'
'=<': 'le'
'<=': 'le'
'[' : 'one_of'
'=~' : 'matches'
'^' : 'first_of'
'{' : 'match_of' # one_of but not exact search
'#=' : 'lene'
'#>' : 'leng'
'#>=' : 'lenge'
'#<' : 'lenl'
'#<=' : 'lenle'
insensitive_operator : 'i'
parse_clauses: (clauses) ->
bads = []
structure = []
unless clauses
return
clauses = clauses.split ' '
for clause in clauses
#Here comes the long and boring validation checking
clause = clause.trim()
if clause.length < 1 then continue
parts = clause.split /:(.+)/
unless parts.length > 1
bads.push [clause, 'Filter clause is not well separated']
continue
unless parts[0] in @filter_fields
bads.push [clause, 'Unknown filter field']
continue
field = parts[0]
if parts[1][0] is @insensitive_operator
sensitive = false
rest = parts[1][1..]
else
sensitive = true
rest = parts[1]
operator_found = false
for operator in @operators
if (rest.indexOf operator) is 0
oper = @operator_mapping[operator]
if operator is '[' or operator is '{'
value = rest[operator.length..].split ','
else
value = rest[operator.length..]
operator_found = true
if field is 'user'
value = 'acct:' + value + '@' + window.location.hostname
break
unless operator_found
bads.push [clause, 'Unknown operator']
continue
structure.push
'field' : '/' + field
'operator': oper
'value' : value
'case_sensitive': sensitive
[structure, bads]
class StreamFilter class StreamFilter
strategies: ['include_any', 'include_all', 'exclude_any', 'exclude_all'] strategies: ['include_any', 'include_all', 'exclude_any', 'exclude_all']
past_modes: ['none','hits','time'] past_modes: ['none','hits','time']
...@@ -94,7 +13,6 @@ class StreamFilter ...@@ -94,7 +13,6 @@ class StreamFilter
load_past: "none" load_past: "none"
constructor: -> constructor: ->
@parser = new ClauseParser()
getFilter: -> return @filter getFilter: -> return @filter
getPastData: -> return @filter.past_data getPastData: -> return @filter.past_data
...@@ -166,29 +84,13 @@ class StreamFilter ...@@ -166,29 +84,13 @@ class StreamFilter
@filter.clauses.push clause @filter.clauses.push clause
this this
addClause: (field, operator, value, case_sensitive = false, es_query_string = false) -> addClause: (field, operator, value, case_sensitive = false, options = {}) ->
@filter.clauses.push @filter.clauses.push
field: field field: field
operator: operator operator: operator
value: value value: value
case_sensitive: case_sensitive case_sensitive: case_sensitive
es_query_string: es_query_string options: options
this
setClausesParse: (clauses_to_parse, error_checking = false) ->
res = @parser.parse_clauses clauses_to_parse
if res[1].length
console.log "Errors while parsing clause:"
console.log res[1]
if res? and (not error_checking) or (error_checking and res[1]?.length is 0)
@filter.clauses = res[0]
this
addClausesParse: (clauses_to_parse, error_checking = false) ->
res = @parser.parse_clauses clauses_to_parse
if res? and (not error_checking) or (error_checking and res[1]?.length is 0)
for clause in res[0]
@filter.clauses.push clause
this this
resetFilter: -> resetFilter: ->
...@@ -202,5 +104,4 @@ class StreamFilter ...@@ -202,5 +104,4 @@ class StreamFilter
angular.module('h.streamfilter',['bootstrap']) angular.module('h.streamfilter',['bootstrap'])
.service('clauseparser', ClauseParser)
.service('streamfilter', StreamFilter) .service('streamfilter', StreamFilter)
\ No newline at end of file
...@@ -33,8 +33,14 @@ get_quote = (annotation) -> ...@@ -33,8 +33,14 @@ get_quote = (annotation) ->
# exact_match: true|false (default: true) # exact_match: true|false (default: true)
# case_sensitive: true|false (default: false) # case_sensitive: true|false (default: false)
# and_or: and|or for multiple values should it threat them as 'or' or 'and' (def: or) # and_or: and|or for multiple values should it threat them as 'or' or 'and' (def: or)
# es_query_string: should the streaming backend use query_string es query for this facet
# operator: if given it'll use this operator regardless of other circumstances # operator: if given it'll use this operator regardless of other circumstances
#
# options: backend specific options
# options.es: elasticsearch specific options
# options.es.query_type : can be: simple, query_string, match
# defaults to: simple, determines which es query type to use
# options.es.cutoff_frequency: if set, the query will be given a cutoff_frequency for this facet
# options.es.and_or: match queries can use this, defaults to and
# } # }
# The models is the direct output from visualsearch # The models is the direct output from visualsearch
# The limit is the default limit # The limit is the default limit
...@@ -71,14 +77,13 @@ class SearchHelper ...@@ -71,14 +77,13 @@ class SearchHelper
case_sensitive = if rule.case_sensitive? then rule.case_sensitive else false case_sensitive = if rule.case_sensitive? then rule.case_sensitive else false
and_or = if rule.and_or? then rule.and_or else 'or' and_or = if rule.and_or? then rule.and_or else 'or'
mapped_field = if rule.path? then rule.path else '/'+category mapped_field = if rule.path? then rule.path else '/'+category
es_query_string = if rule.es_query_string? then rule.es_query_string else false
if values.length is 1 if values.length is 1
oper_part = oper_part =
if rule.operator? then rule.operator if rule.operator? then rule.operator
else if exact_match then 'equals' else 'matches' else if exact_match then 'equals' else 'matches'
value_part = if rule.formatter then rule.formatter values[0] else values[0] value_part = if rule.formatter then rule.formatter values[0] else values[0]
filter.addClause mapped_field, oper_part, value_part, case_sensitive, es_query_string filter.addClause mapped_field, oper_part, value_part, case_sensitive, rule.options
else else
if and_or is 'or' if and_or is 'or'
val_list = '' val_list = ''
...@@ -90,14 +95,14 @@ class SearchHelper ...@@ -90,14 +95,14 @@ class SearchHelper
oper_part = oper_part =
if rule.operator? then rule.operator if rule.operator? then rule.operator
else if exact_match then 'one_of' else 'match_of' else if exact_match then 'one_of' else 'match_of'
filter.addClause mapped_field, oper_part, val_list, case_sensitive, es_query_string filter.addClause mapped_field, oper_part, val_list, case_sensitive, rule.options
else else
oper_part = oper_part =
if rule.operator? then rule.operator if rule.operator? then rule.operator
else if exact_match then 'equals' else 'matches' else if exact_match then 'equals' else 'matches'
for val in values for val in values
value_part = if rule.formatter then rule.formatter val else val value_part = if rule.formatter then rule.formatter val else val
filter.addClause mapped_field, oper_part, value_part, case_sensitive, es_query_string filter.addClause mapped_field, oper_part, value_part, case_sensitive, rule.options
if limit != 50 then categories['results'] = [limit] if limit != 50 then categories['results'] = [limit]
[filter.getFilter(), categories] [filter.getFilter(), categories]
...@@ -132,16 +137,17 @@ class StreamSearch ...@@ -132,16 +137,17 @@ class StreamSearch
and_or: 'and' and_or: 'and'
uri: uri:
formatter: (uri) -> formatter: (uri) ->
uri = uri.toLowerCase() uri.toLowerCase()
if uri.match(/http:\/\//) then uri = uri.substring(7)
if uri.match(/https:\/\//) then uri = uri.substring(8)
if uri.match(/^www\./) then uri = uri.substring(4)
uri
path: '/uri' path: '/uri'
exact_match: false exact_match: false
case_sensitive: false case_sensitive: false
es_query_string: true
and_or: 'or' and_or: 'or'
options:
es:
query_type: 'match'
cutoff_frequency: 0.001
and_or: 'and'
since: since:
formatter: (past) -> formatter: (past) ->
seconds = seconds =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment