查询定义 除了数据定义,实现搜索API还需要查询定义。我们已经创建了一组类,用来实现亚马逊的查询定义。 这个搜索查询的核心是过滤器。我们引入了SearchQueryFilter 接口,并提供了两种实现方式——Search Query Value Filter(列表3)和Search Query Filter Operation(列表4)。 public class SearchQueryValueFilter implements SearchQueryFilter{ private String _field; private String _value; private boolean _isExclude; private boolean _isNumeric; public SearchQueryValueFilter(){} public SearchQueryValueFilter(String field, String value, boolean isNumeric, boolean isExclude){ _field = field; _value = value; _isExclude = isExclude; _isNumeric = isNumeric; } public String getField() { return _field; } public void setField(String field) { _field = field; } public String getValue() { return _value; } public void setValue(String value) { _value = value; } public boolean isExclude() { return _isExclude; } public void setExclude(boolean isExclude) { _isExclude = isExclude; } public boolean isNumeric() { return _isNumeric; } public void setNumeric(boolean isNumeric) { _isNumeric = isNumeric; } @Override public String toString(){ StringBuffer sb = new StringBuffer(); if(_isExclude){ sb.append("(not "); } if(_field != null){ sb.append(_field); sb.append(":"); } if(!_isNumeric){ sb.append("'"); } sb.append(_value); if(!_isNumeric){ sb.append("'"); } if(_isExclude){ sb.append(")"); } return sb.toString(); } } Listing 3 Value filter implementation public class SearchQueryFilterOperation implements SearchQueryFilter { List<SearchQueryFilter> _filters; FilterOperation _operation; public SearchQueryFilterOperation(){ _operation = FilterOperation.and; _filters = new LinkedList<SearchQueryFilter>(); } public List<SearchQueryFilter> getFilters() { return _filters; } public void setFilters(List<SearchQueryFilter> filters) { _filters = filters; } public void addFilters(SearchQueryFilter filter) { _filters.add(filter); } public FilterOperation getOperation() { return _operation; } public void setOperation(FilterOperation operation) { _operation = operation; } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("("); sb.append(_operation); for(SearchQueryFilter f : _filters){ sb.append(" "); sb.append(f); } sb.append(")"); return sb.toString(); } public enum FilterOperation{ and, or } } Listing 4 Operation filter implementation Search Query Value Filter类支持开发者使用等于、小于、大于、区间(同样支持负值比较)等运算符设置单个字段的限制。而Search Query Filter Operation类还支持开发者使用AND/OR操作符,将多个Search Query Value Filters和Search Query Filter Operations组合使用。通过这两个类的组合使用,就能实现亚马逊云搜索所支持的任意查询过滤器的表达式了。 亚马逊云搜索支持分面分类(Faceted classification):
分面分类应用于分面搜索系统,用户在这种系统中能够从多方面进行信息的导航(译者注:如书籍可以从作者、主题、出版日期等不同的分面),多方面对应于不同顺序的分面。 AWS支持按分面控制搜索执行以及对搜索结果排序。同时还支持开发者控制返回的搜索结果中包含的分面数量。所有的分面操作由Search Query Facet(列表5)这个类来实现。 public class SearchQueryFacet { private String _name; private int _maxFacets; private List<String> _constraints; private FacetSort _sort; public SearchQueryFacet(String name){ _name = name; _maxFacets = -1; _constraints = null; _sort = FacetSort.none; } public SearchQueryFacet(String name, int maxFacets){ _name = name; _maxFacets = maxFacets; _constraints = null; _sort = FacetSort.none; } public SearchQueryFacet(String name, int maxFacets, FacetSort sort){ _name = name; _maxFacets = maxFacets; _constraints = null; _sort = sort; } public SearchQueryFacet(String name, int maxFacets, List<String> constraints){ _name = name; _maxFacets = maxFacets; _constraints = constraints; _sort = FacetSort.none; } public SearchQueryFacet(String name, List<String> constraints){ _name = name; _maxFacets = -1; _constraints = constraints; _sort = FacetSort.none; } public SearchQueryFacet(String name, FacetSort sort, List<String> constraints){ _name = name; _maxFacets = -1; _constraints = constraints; _sort = sort; } public SearchQueryFacet(String name, FacetSort sort){ _name = name; _maxFacets = -1; _constraints = null; _sort = sort; } public String getName() { return _name; } public void setName(String name) { _name = name; } public int getMaxFacets() { return _maxFacets; } public void setMaxFacets(int maxFacets) { _maxFacets = maxFacets; } public FacetSort getSort() { return _sort; } public void setSort(FacetSort sort) { _sort = sort; } public int get_maxFacets() { return _maxFacets; } public void set_maxFacets(int _maxFacets) { this._maxFacets = _maxFacets; } public List<String> getConstraints() { return _constraints; } public void setConstraints(List<String> constraints) { _constraints = constraints; } public void addConstraint(String constraint) { if(_constraints == null) _constraints = new LinkedList<String>(); _constraints.add(constraint); } @Override public String toString(){ StringBuffer sb = new StringBuffer(); sb.append("&facet="); sb.append(_name); if(_maxFacets > 0){ sb.append("&facet-"); sb.append(_name); sb.append("-top-n="); sb.append(_maxFacets); } if((_constraints != null) && (_constraints.size() > 0)){ sb.append("&facet-"); sb.append(_name); sb.append("-constraints="); boolean first = true; for(String c : _constraints){ if(!first) sb.append("%2C"); else first = false; sb.append("%27"); sb.append(c); sb.append("%27"); } } if(!_sort.equals(FacetSort.none)){ sb.append("&facet-"); sb.append(_name); sb.append("-sort="); sb.append(_sort); } return sb.toString(); } public enum FacetSort{ none, alpha, count, max, sum } } Listing 5 Facets control class |