def get(self, request): #takes a latitude and longitude and returns artifacts within 2 miles try: lon = float(request.GET.get('lon', None)) lat = float(request.GET.get('lat', None)) except: return HttpResponse('You Must Specify a latitude and longitude', content_type='application/json', status=status.HTTP_400_BAD_REQUEST) username = request.user.username pnt = Point(lon, lat) # Within a two miles. max_dist = D(mi=2) # 'location' is the fieldname from our ``SearchIndex``... # Do the radius query. sqs = SearchQuerySet().distance('location',pnt).order_by('distance') within = sqs.dwithin('location', pnt, max_dist) if len(within) != len(sqs) and len(within) !=0 and len(sqs) !=0: closest_not_within = pnt.distance(sqs[len(within)])*100*0.6214 else: closest_not_within='null' the_data = [] for result in sqs: # get number of pickups as well as whether or not the user has already picked up already_picked_up = (username in result.pickup_count) _pickup_count = count_m2m(result.pickup_count) # get number of upvotes as well as whether or not the user has already upvoted already_upvoted = (username in result.upvoted) upvote_count = count_m2m(result.upvoted) # make a point artifactpnt = Point(float(result.longitude), float(result.latitude)) loopy_data = {'author': result.author, 'upvote_count': upvote_count, 'already_upvoted': already_upvoted, 'already_picked_up': already_picked_up, 'longitude': result.longitude, 'radius': result.radius, 'latitude': result.latitude, 'pub_date': str(result.pub_date), 'pickup_count': _pickup_count, 'distance': (artifactpnt.distance(pnt) *100)* 0.6214, 'pk': result.pk} the_data += [loopy_data] the_data = [json.dumps(the_data + [{'closest_not_within':closest_not_within}])] return HttpResponse(the_data, content_type='application/json', status=status.HTTP_200_OK)
def get_near_items(item): #import ipdb; ipdb.set_trace() qs = SearchQuerySet().all() loc = item.locations.first() point = Point(loc.lng, loc.lat) qs = qs.dwithin('location', point, D(m=50000)).distance('location', point) qs = qs.narrow('%s:"%s"' % ('groups_exact', 'public')) return qs
def get_potential_doubles(self): """ Returns an instance list of potential double for this race, based on : - distance (<10km) - date (+- 1 day) - samed distance category """ sqs = SearchQuerySet() pk = self.pk if pk: sqs = sqs.exclude(django_id=pk) sqs = sqs.dwithin('location', self.location.get_point(), D(km=10)) sqs = sqs.filter( date__gte=self.date + datetime.timedelta(days=-1), date__lte=self.date + datetime.timedelta(days=1), distance_cat=self.distance_cat.name, sport__exact=self.sport.name, # event_title=self.event.name ) # return race objects instead of haystack searchresul return [sr.object for sr in sqs]
def get_search(self, request, **kwargs): self.method_check(request, allowed=['get']) self.is_authenticated(request) self.throttle_check(request) try: page_count = min(int(request.GET.get('limit', 20)), 500) page_nr = int(request.GET.get('page', 1)) if page_count <= 0 or page_nr <= 0: raise ValueError() except ValueError: raise BadRequest("'limit' and 'page' must be positive integers") sqs = SearchQuerySet().models(Issue).load_all() query = request.GET.get('text', '').strip() if query: sqs = sqs.auto_query(query).highlight() order_by = None else: order_by = '-latest_decision_date' s = request.GET.get('order_by', '').lower() if s: if s[0] == '-': reverse = True s = s[1:] else: reverse = False if s not in ('latest_decision_date', 'relevance'): raise BadRequest("'order_by' must either be for 'latest_decision_date' or 'relevance'") if reverse: order_by = '-' + s else: order_by = s if s == 'relevance': order_by = None if order_by: sqs = sqs.order_by(order_by) category = request.GET.get('category', '').strip() if category: try: cat_nr = int(category) except ValueError: raise BadRequest("'category' must be a positive integer") # Search in all ancestor categories, too sqs = sqs.filter(categories=cat_nr) district = request.GET.get('district', '').strip() if district: d_list = district.split(',') sqs = sqs.filter(districts__in=d_list) bbox = request.GET.get('bbox', '').strip() if bbox: poly = poly_from_bbox(bbox) e = poly.extent bottom_left = HaystackPoint(e[0], e[1]) top_right = HaystackPoint(e[2], e[3]) sqs = sqs.within('location', bottom_left, top_right) distance = request.GET.get('distance', '').strip() latitude = request.GET.get('lat', '').strip() longitude = request.GET.get('lon', '').strip() if distance and latitude and longitude: haystack_point = HaystackPoint(float(longitude), float(latitude)) sqs = sqs.dwithin('location', haystack_point, D(m=distance)) if order_by: sqs = sqs.order_by(order_by) policymaker = request.GET.get('policymaker', '').strip() if policymaker: pm_list = policymaker.split(',') try: pm_list = [int(x) for x in pm_list] except ValueError: raise BadRequest("'policymaker' must be a list of positive integers") sqs = sqs.filter(policymakers__in=pm_list) paginator = Paginator(sqs, page_count) try: page = paginator.page(page_nr) except InvalidPage: return HttpResponseNotFound("Sorry, no results on that page.") objects = [] for result in page.object_list: bundle = self.build_bundle(obj=result.object, request=request) bundle = self.full_dehydrate(bundle) if result.highlighted and 'text' in result.highlighted: bundle.data['search_highlighted'] = result.highlighted['text'][0] objects.append(bundle) total_count = sqs.count() object_list = { 'objects': objects, 'meta': {'page': page_nr, 'limit': page_count, 'total_count': total_count} } self.log_throttled_access(request) return self.create_response(request, object_list)
def get_dateo_stats(self, request, **kwargs): self.method_check(request, allowed=['get']) self.throttle_check(request) # Do the query q_args = {'published': request.GET.get('published', True)} # add search query if 'q' in request.GET and request.GET['q'] != '': q_args['content'] = AutoQuery(request.GET['q']) # check for more params params = ['category_id', 'category', 'user', 'user_id', 'published', 'status', 'id', 'created__year', 'created__month', 'created__day', 'country', 'admin_level1', 'admin_level2', 'admin_level3', 'has_images'] for p in params: if p in request.GET: q_args[self.rename_get_filters.get(p, p)] = request.GET.get(p) # check for additional date filters (with datetime objects) date_params = ['created__gt', 'created__lt', 'since', 'until'] for p in date_params: if p in request.GET: q_args[self.rename_get_filters.get(p, p)] = models.DateTimeField().to_python(request.get(p)) tags = [] if 'tags' in request.GET: tags = request.GET.get('tags').split(',') if len(tags) == 1 and tags[0].strip() != '': q_args['tags_exact'] = tags[0].lower() else: q_args['tags_exact__in'] = [t.lower() for t in tags] if 'campaign' in request.GET: cam = Campaign.objects.get(pk=int(request.GET.get('campaign'))) tags = [c.tag for c in cam.secondary_tags.all()] if len(tags) == 1 and tags[0].strip() != '': q_args['tags_exact'] = tags[0].lower() else: q_args['tags_exact__in'] = [t.lower() for t in tags] filter_by_dateos = False # INIT THE QUERY sqs = SearchQuerySet().models(Dateo).load_all().filter(**q_args) if len(q_args) > 1: filter_by_dateos = True # SPATIAL QUERY ADDONS # WITHIN QUERY if all(k in request.GET and request.GET.get(k) != '' for k in ('bottom_left_latitude', 'bottom_left_longitude','top_right_latitude', 'top_right_longitude')): bl_x = float(request.GET.get('bottom_left_longitude')) bl_y = float(request.GET.get('bottom_left_latitude')) tr_x = float(request.GET.get('top_right_longitude')) tr_y = float(request.GET.get('top_right_latitude')) bottom_left = Point(bl_x, bl_y) top_right = Point(tr_x, tr_y) sqs = sqs.within('position', bottom_left, top_right) filter_by_dateos = True # DWITHIN QUERY if all(k in request.GET and request.GET.get(k) != '' for k in ('distance', 'latitude', 'longitude')): dist = Distance( m = request.GET.get('distance')) x = float(request.GET.get('longitude')) y = float(request.GET.get('latitude')) position = Point(x, y) sqs = sqs.dwithin('position', position, dist) filter_by_dateos = True response = { 'dateo_count': sqs.count(), } if filter_by_dateos: dateo_pks = [d.obj_id for d in sqs] # TAGS if len(tags) > 0: tag_objects = Tag.objects.filter(tag__in=tags) if filter_by_dateos: tag_objects = tag_objects.filter(dateos__pk__in=dateo_pks).distinct() tags_result = [] for t in tag_objects: tags_result.append({ 'count': t.dateo_count, 'tag': t.tag, 'title': t.title, 'id': t.pk }) response['tags'] = tags_result # USERS user_objects = User.objects.filter(is_active=True, status=1) if filter_by_dateos: user_objects = user_objects.filter(dateos__pk__in=dateo_pks).distinct() response['user_count'] = user_objects.count() self.log_throttled_access(request) return self.create_response(request, response)
def get_search(self, request, **kwargs): # tests self.method_check(request, allowed=['get']) #self.is_authenticated(request) self.throttle_check(request) # pagination limit = int(request.GET.get('limit', 100)) offset = int(request.GET.get('offset', 0)) page = (offset / limit) + 1 # Build query args q_args = {'published': request.GET.get('published', True)} narrow_args = [] # add search query if 'q' in request.GET and request.GET['q'] != '': q_args['content'] = AutoQuery(remove_accents(request.GET['q'])) # check for more params params = ['category_id', 'category', 'user', 'user_id', 'status', 'id', 'created__year', 'created__month', 'created__day', 'country', 'admin_level1', 'admin_level2', 'admin_level3', 'has_images', 'is_geolocated', 'admin'] for p in params: if p in request.GET: q_args[self.rename_get_filters.get(p, p)] = request.GET.get(p) # check for additional date filters (with datetime objects) date_params = ['created__gt', 'created__lt', 'since', 'until'] for p in date_params: if p in request.GET: q_args[self.rename_get_filters.get(p, p)] = models.DateTimeField().to_python(request.GET.get(p)) if 'narrow_on_tags' in request.GET: tags = map(normalize_tag, request.GET.get('narrow_on_tags').split(',')) narrow_args.append('tags:'+','.join(tags)) if 'tags' in request.GET: tag_op = request.GET.get('tag_operator', 'or') tags = map(normalize_tag, request.GET.get('tags').split(',')) if tag_op == 'or': if len(tags) == 1 and tags[0].strip() != '': q_args['tags__exact'] = tags[0] else: q_args['tags__exact__in'] = tags elif tag_op == 'and': narrow_args.append('tags:'+','.join(tags)) # GET ONLY DATEOS I FOLLOW INDIVIDUALLY if 'followed' in request.GET: uid = int(request.GET['followed']) dateo_ids = [f.object_id for f in Follow.objects.filter(content_type__model='dateo', user__id=uid)] q_args['id__in'] = dateo_ids # GET DATEOS BY TAGS I FOLLOW if 'followed_by_tags' in request.GET: uid = int(request.GET['followed_by_tags']) tags = [f.content_object.tag for f in Follow.objects.filter(content_type__model='tag', user__id=uid)] q_args['tags__in'] = tags # show published and unpublished actions if q_args['published'] == 'all': del q_args['published'] # INCLUDE REDATEOS (or not) search_models = [Dateo] if 'include_redateos' in request.GET and request.GET.get('include_redateos'): search_models.append(Redateo) # INIT THE QUERY sqs = SearchQuerySet().models(*search_models).load_all() for narg in narrow_args: sqs = sqs.narrow(narg) sqs = sqs.filter(**q_args) # SPATIAL QUERY ADDONS # WITHIN QUERY if all(k in request.GET and request.GET.get(k) != '' for k in ('bottom_left_latitude', 'bottom_left_longitude','top_right_latitude', 'top_right_longitude')): bl_x = float(request.GET.get('bottom_left_longitude')) bl_y = float(request.GET.get('bottom_left_latitude')) tr_x = float(request.GET.get('top_right_longitude')) tr_y = float(request.GET.get('top_right_latitude')) bottom_left = Point(bl_x, bl_y) top_right = Point(tr_x, tr_y) sqs = sqs.within('position', bottom_left, top_right) # DWITHIN QUERY if all(k in request.GET and request.GET.get(k) != '' for k in ('distance', 'latitude', 'longitude')): dist = Distance( m = request.GET.get('distance')) x = float(request.GET.get('longitude')) y = float(request.GET.get('latitude')) position = Point(x, y) sqs = sqs.dwithin('position', position, dist) # ADMIN CASE -> only new dateos if 'new_in_campaign_id' in request.GET: campaign_id = str(request.GET.get('new_in_campaign_id')) sqs = sqs.exclude(admin__in=['reviewed:'+campaign_id, 'solved:'+campaign_id]) # ORDER BY order_by = request.GET.get('order_by', '-created').split(',') # if q is set, then order will be relevance first # if not, then do normal order by if 'q' in request.GET: if order_by == ['-created'] and 'order_by' not in request.GET: #order_by = ['_score'] order_by = ['score'] # if order_by distance, then things change a bit if 'distance' in order_by and 'position' in request.GET and request.GET['position'] != '': pos = [float(c) for c in request.GET.get('position').split(',')] position = Point(pos[0], pos[1]) sqs = sqs.distance('position', position).order_by('distance', *order_by) elif len(order_by) > 0: sqs = sqs.order_by(*order_by) paginator = Paginator(sqs, limit) try: page = paginator.page(page) except InvalidPage: raise Http404("Sorry, no results on that page.") objects = [] for result in page.object_list: res_obj = result.object if result.model_name == 'dateo' else result.object.dateo cache_key = 'dateo.'+str(res_obj.pk) data = self._meta.cache.get(cache_key) if not data: bundle = self.build_bundle(obj=res_obj, request=request) bundle = self.full_dehydrate(bundle) data = self._meta.cache.set(cache_key, bundle) objects.append(data) object_list = { 'meta': { 'limit': limit, 'next': page.has_next(), 'previous': page.has_previous(), 'total_count': sqs.count(), 'offset': offset }, 'objects': objects, } self.log_throttled_access(request) return self.create_response(request, object_list)
class SpatialSolrTestCase(TestCase): fixtures = ["sample_spatial_data.json"] using = "solr" def setUp(self): super(SpatialSolrTestCase, self).setUp() self.ui = connections[self.using].get_unified_index() self.checkindex = self.ui.get_index(Checkin) self.checkindex.reindex(using=self.using) self.sqs = SearchQuerySet().using(self.using) self.downtown_pnt = Point(-95.23592948913574, 38.97127105172941) self.downtown_bottom_left = Point(-95.23947, 38.9637903) self.downtown_top_right = Point(-95.23362278938293, 38.973081081164715) self.lawrence_bottom_left = Point(-95.345535, 39.002643) self.lawrence_top_right = Point(-95.202713, 38.923626) def tearDown(self): self.checkindex.clear(using=self.using) super(SpatialSolrTestCase, self).setUp() def test_indexing(self): # Make sure the indexed data looks correct. first = Checkin.objects.get(pk=1) sqs = self.sqs.models(Checkin).filter(django_id=first.pk) self.assertEqual(sqs.count(), 1) self.assertEqual(sqs[0].username, first.username) # Make sure we've got a proper ``Point`` object. self.assertAlmostEqual(sqs[0].location.coords[0], first.longitude) self.assertAlmostEqual(sqs[0].location.coords[1], first.latitude) # Double-check, to make sure there was nothing accidentally copied # between instances. second = Checkin.objects.get(pk=2) self.assertNotEqual(second.latitude, first.latitude) sqs = self.sqs.models(Checkin).filter(django_id=second.pk) self.assertEqual(sqs.count(), 1) self.assertEqual(sqs[0].username, second.username) self.assertAlmostEqual(sqs[0].location.coords[0], second.longitude) self.assertAlmostEqual(sqs[0].location.coords[1], second.latitude) def test_within(self): self.assertEqual(self.sqs.all().count(), 10) sqs = self.sqs.within("location", self.downtown_bottom_left, self.downtown_top_right) self.assertEqual(sqs.count(), 7) sqs = self.sqs.within("location", self.lawrence_bottom_left, self.lawrence_top_right) self.assertEqual(sqs.count(), 9) def test_dwithin(self): self.assertEqual(self.sqs.all().count(), 10) sqs = self.sqs.dwithin("location", self.downtown_pnt, D(mi=0.1)) self.assertEqual(sqs.count(), 5) sqs = self.sqs.dwithin("location", self.downtown_pnt, D(mi=0.5)) self.assertEqual(sqs.count(), 7) sqs = self.sqs.dwithin("location", self.downtown_pnt, D(mi=100)) self.assertEqual(sqs.count(), 10) def test_distance_added(self): sqs = self.sqs.within("location", self.downtown_bottom_left, self.downtown_top_right).distance( "location", self.downtown_pnt) self.assertEqual(sqs.count(), 7) self.assertAlmostEqual(sqs[0].distance.mi, 0.01985226) self.assertAlmostEqual(sqs[1].distance.mi, 0.03385863) self.assertAlmostEqual(sqs[2].distance.mi, 0.04539100) self.assertAlmostEqual(sqs[3].distance.mi, 0.04831436) self.assertAlmostEqual(sqs[4].distance.mi, 0.41116546) self.assertAlmostEqual(sqs[5].distance.mi, 0.25098114) self.assertAlmostEqual(sqs[6].distance.mi, 0.04831436) sqs = self.sqs.dwithin("location", self.downtown_pnt, D(mi=0.1)).distance("location", self.downtown_pnt) self.assertEqual(sqs.count(), 5) self.assertAlmostEqual(sqs[0].distance.mi, 0.01985226) self.assertAlmostEqual(sqs[1].distance.mi, 0.03385863) self.assertAlmostEqual(sqs[2].distance.mi, 0.04539100) self.assertAlmostEqual(sqs[3].distance.mi, 0.04831436) self.assertAlmostEqual(sqs[4].distance.mi, 0.04831436) def test_order_by_distance(self): sqs = (self.sqs.within("location", self.downtown_bottom_left, self.downtown_top_right).distance( "location", self.downtown_pnt).order_by("distance")) self.assertEqual(sqs.count(), 7) self.assertEqual([result.pk for result in sqs], ["8", "9", "6", "3", "1", "2", "5"]) self.assertEqual( ["%0.04f" % result.distance.mi for result in sqs], [ "0.0199", "0.0339", "0.0454", "0.0483", "0.0483", "0.2510", "0.4112" ], ) sqs = (self.sqs.dwithin("location", self.downtown_pnt, D(mi=0.1)).distance( "location", self.downtown_pnt).order_by("distance")) self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ["8", "9", "6", "3", "1"]) self.assertEqual( ["%0.04f" % result.distance.mi for result in sqs], ["0.0199", "0.0339", "0.0454", "0.0483", "0.0483"], ) sqs = (self.sqs.dwithin("location", self.downtown_pnt, D(mi=0.1)).distance( "location", self.downtown_pnt).order_by("-distance")) self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ["3", "1", "6", "9", "8"]) self.assertEqual( ["%0.04f" % result.distance.mi for result in sqs], ["0.0483", "0.0483", "0.0454", "0.0339", "0.0199"], ) def test_complex(self): sqs = (self.sqs.auto_query("coffee").within( "location", self.downtown_bottom_left, self.downtown_top_right).distance( "location", self.downtown_pnt).order_by("distance")) self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ["8", "6", "3", "1", "2"]) self.assertEqual( ["%0.04f" % result.distance.mi for result in sqs], ["0.0199", "0.0454", "0.0483", "0.0483", "0.2510"], ) sqs = (self.sqs.auto_query("coffee").dwithin( "location", self.downtown_pnt, D(mi=0.1)).distance("location", self.downtown_pnt).order_by("distance")) self.assertEqual(sqs.count(), 4) self.assertEqual([result.pk for result in sqs], ["8", "6", "3", "1"]) self.assertEqual( ["%0.04f" % result.distance.mi for result in sqs], ["0.0199", "0.0454", "0.0483", "0.0483"], ) sqs = (self.sqs.auto_query("coffee").dwithin( "location", self.downtown_pnt, D(mi=0.1)).distance("location", self.downtown_pnt).order_by("-distance")) self.assertEqual(sqs.count(), 4) self.assertEqual([result.pk for result in sqs], ["3", "1", "6", "8"]) self.assertEqual( ["%0.04f" % result.distance.mi for result in sqs], ["0.0483", "0.0483", "0.0454", "0.0199"], ) sqs = (self.sqs.auto_query("coffee").within( "location", self.downtown_bottom_left, self.downtown_top_right).distance( "location", self.downtown_pnt).order_by("-created")) self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ["8", "6", "3", "2", "1"]) sqs = (self.sqs.auto_query("coffee").dwithin( "location", self.downtown_pnt, D(mi=0.1)).distance("location", self.downtown_pnt).order_by("-created")) self.assertEqual(sqs.count(), 4) self.assertEqual([result.pk for result in sqs], ["8", "6", "3", "1"])
class SpatialSolrTestCase(TestCase): fixtures = ['sample_spatial_data.json'] using = 'solr' def setUp(self): super(SpatialSolrTestCase, self).setUp() self.ui = connections[self.using].get_unified_index() self.checkindex = self.ui.get_index(Checkin) self.checkindex.reindex(using=self.using) self.sqs = SearchQuerySet().using(self.using) self.downtown_pnt = Point(-95.23592948913574, 38.97127105172941) self.downtown_bottom_left = Point(-95.23947, 38.9637903) self.downtown_top_right = Point(-95.23362278938293, 38.973081081164715) self.lawrence_bottom_left = Point(-95.345535, 39.002643) self.lawrence_top_right = Point(-95.202713, 38.923626) def tearDown(self): self.checkindex.clear(using=self.using) super(SpatialSolrTestCase, self).setUp() def test_indexing(self): # Make sure the indexed data looks correct. first = Checkin.objects.get(pk=1) sqs = self.sqs.models(Checkin).filter(django_id=first.pk) self.assertEqual(sqs.count(), 1) self.assertEqual(sqs[0].username, first.username) # Make sure we've got a proper ``Point`` object. self.assertAlmostEqual(sqs[0].location.get_coords()[0], first.longitude) self.assertAlmostEqual(sqs[0].location.get_coords()[1], first.latitude) # Double-check, to make sure there was nothing accidentally copied # between instances. second = Checkin.objects.get(pk=2) self.assertNotEqual(second.latitude, first.latitude) sqs = self.sqs.models(Checkin).filter(django_id=second.pk) self.assertEqual(sqs.count(), 1) self.assertEqual(sqs[0].username, second.username) self.assertAlmostEqual(sqs[0].location.get_coords()[0], second.longitude) self.assertAlmostEqual(sqs[0].location.get_coords()[1], second.latitude) def test_within(self): self.assertEqual(self.sqs.all().count(), 10) sqs = self.sqs.within('location', self.downtown_bottom_left, self.downtown_top_right) self.assertEqual(sqs.count(), 7) sqs = self.sqs.within('location', self.lawrence_bottom_left, self.lawrence_top_right) self.assertEqual(sqs.count(), 9) def test_dwithin(self): self.assertEqual(self.sqs.all().count(), 10) sqs = self.sqs.dwithin('location', self.downtown_pnt, D(mi=0.1)) self.assertEqual(sqs.count(), 5) sqs = self.sqs.dwithin('location', self.downtown_pnt, D(mi=0.5)) self.assertEqual(sqs.count(), 7) sqs = self.sqs.dwithin('location', self.downtown_pnt, D(mi=100)) self.assertEqual(sqs.count(), 10) def test_distance_added(self): sqs = self.sqs.within('location', self.downtown_bottom_left, self.downtown_top_right).distance('location', self.downtown_pnt) self.assertEqual(sqs.count(), 7) self.assertAlmostEqual(sqs[0].distance.mi, 0.01985226) self.assertAlmostEqual(sqs[1].distance.mi, 0.03385863) self.assertAlmostEqual(sqs[2].distance.mi, 0.04539100) self.assertAlmostEqual(sqs[3].distance.mi, 0.04831436) self.assertAlmostEqual(sqs[4].distance.mi, 0.41116546) self.assertAlmostEqual(sqs[5].distance.mi, 0.25098114) self.assertAlmostEqual(sqs[6].distance.mi, 0.04831436) sqs = self.sqs.dwithin('location', self.downtown_pnt, D(mi=0.1)).distance('location', self.downtown_pnt) self.assertEqual(sqs.count(), 5) self.assertAlmostEqual(sqs[0].distance.mi, 0.01985226) self.assertAlmostEqual(sqs[1].distance.mi, 0.03385863) self.assertAlmostEqual(sqs[2].distance.mi, 0.04539100) self.assertAlmostEqual(sqs[3].distance.mi, 0.04831436) self.assertAlmostEqual(sqs[4].distance.mi, 0.04831436) def test_order_by_distance(self): sqs = self.sqs.within('location', self.downtown_bottom_left, self.downtown_top_right).distance('location', self.downtown_pnt).order_by('distance') self.assertEqual(sqs.count(), 7) self.assertEqual([result.pk for result in sqs], ['8', '9', '6', '3', '1', '2', '5']) self.assertEqual(["%0.04f" % result.distance.mi for result in sqs], ['0.0199', '0.0339', '0.0454', '0.0483', '0.0483', '0.2510', '0.4112']) sqs = self.sqs.dwithin('location', self.downtown_pnt, D(mi=0.1)).distance('location', self.downtown_pnt).order_by('distance') self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ['8', '9', '6', '3', '1']) self.assertEqual(["%0.04f" % result.distance.mi for result in sqs], ['0.0199', '0.0339', '0.0454', '0.0483', '0.0483']) sqs = self.sqs.dwithin('location', self.downtown_pnt, D(mi=0.1)).distance('location', self.downtown_pnt).order_by('-distance') self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ['3', '1', '6', '9', '8']) self.assertEqual(["%0.04f" % result.distance.mi for result in sqs], ['0.0483', '0.0483', '0.0454', '0.0339', '0.0199']) def test_complex(self): sqs = self.sqs.auto_query('coffee').within('location', self.downtown_bottom_left, self.downtown_top_right).distance('location', self.downtown_pnt).order_by('distance') self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ['8', '6', '3', '1', '2']) self.assertEqual(["%0.04f" % result.distance.mi for result in sqs], ['0.0199', '0.0454', '0.0483', '0.0483', '0.2510']) sqs = self.sqs.auto_query('coffee').dwithin('location', self.downtown_pnt, D(mi=0.1)).distance('location', self.downtown_pnt).order_by('distance') self.assertEqual(sqs.count(), 4) self.assertEqual([result.pk for result in sqs], ['8', '6', '3', '1']) self.assertEqual(["%0.04f" % result.distance.mi for result in sqs], ['0.0199', '0.0454', '0.0483', '0.0483']) sqs = self.sqs.auto_query('coffee').dwithin('location', self.downtown_pnt, D(mi=0.1)).distance('location', self.downtown_pnt).order_by('-distance') self.assertEqual(sqs.count(), 4) self.assertEqual([result.pk for result in sqs], ['3', '1', '6', '8']) self.assertEqual(["%0.04f" % result.distance.mi for result in sqs], ['0.0483', '0.0483', '0.0454', '0.0199']) sqs = self.sqs.auto_query('coffee').within('location', self.downtown_bottom_left, self.downtown_top_right).distance('location', self.downtown_pnt).order_by('-created') self.assertEqual(sqs.count(), 5) self.assertEqual([result.pk for result in sqs], ['8', '6', '3', '2', '1']) sqs = self.sqs.auto_query('coffee').dwithin('location', self.downtown_pnt, D(mi=0.1)).distance('location', self.downtown_pnt).order_by('-created') self.assertEqual(sqs.count(), 4) self.assertEqual([result.pk for result in sqs], ['8', '6', '3', '1'])
def rides_search(request): sqs = SearchQuerySet() distance = D(mi=20) if request.method == 'POST': searchForm = SearchForm(request.POST) if searchForm.is_valid(): fromLat = searchForm.cleaned_data['fromLat'] fromLng = searchForm.cleaned_data['fromLng'] toLat = searchForm.cleaned_data['toLat'] toLng = searchForm.cleaned_data['toLng'] if fromLat and fromLng: fromPoint = Point(float(fromLng), float(fromLat)) sqs = sqs.dwithin('fromLocation', fromPoint, distance) else: fromPoint = None if toLat and toLng: toPoint = Point(float(searchForm.cleaned_data['toLng']), float(searchForm.cleaned_data['toLat'])) sqs = sqs.dwithin('toLocation', toPoint, distance) else: toPoint = None if searchForm.cleaned_data['leavingOn']: sqs = sqs.filter(leavingOn__exact=searchForm.cleaned_data['leavingOn']) else: sqs = sqs.filter(leavingOn__gte=datetime.date.today()) paginator = Paginator(sqs, 10) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("No such page of results!") context = { 'form': SearchForm(), 'page': page, 'paginator': paginator, 'query': True, 'suggestion': None, 'fromLat': fromLat, 'fromLng': fromLng, 'toLat': toLat, 'toLng': toLng, } else: sqs = sqs.filter(leavingOn__gte=datetime.date.today()) paginator = Paginator(sqs, 10) try: page = paginator.page(int(request.GET.get('page', 1))) except InvalidPage: raise Http404("No such page of results!") context = { 'form': SearchForm(), 'page': page, 'paginator': paginator, 'query': False, 'suggestion': None, } return render(request, 'rides/search.html', context)
def get_queryset(self, *args, **kwargs): qs = SearchQuerySet().all() qs = qs.facet('categories') if self.request.user.is_authenticated(): qs = qs.facet('groups') if self.request.query_params.get('q'): #qs = qs.filter_and(title__contains=self.request.query_params.get('q')) qs = qs.auto_query(self.request.query_params.get('q')) distance = None try: for k, v in self.request.query_params.items(): if k in D.UNITS.keys(): distance = {k: v} except Exception as e: logging.error(e) point = None try: point = Point(float(self.request.query_params['lng']), float(self.request.query_params['lat'])) except Exception as e: logging.error(e) if distance and point: qs = qs or SearchQuerySet() qs = qs.dwithin('location', point, D(**distance)).distance('location', point) try: if self.request.query_params.get('w') and self.request.query_params.get('s')\ and self.request.query_params.get('n') and self.request.query_params.get('e'): bottom_left = Point(float(self.request.query_params['w']), float(self.request.query_params['s'])) top_right = Point(float(self.request.query_params['e']), float(self.request.query_params['n'])) qs = qs.within('location', bottom_left, top_right) except: pass param_facet_url = self.request.query_params.get('selected_facets', '').split(',') flag_group = False for param_facet in param_facet_url: if ":" not in param_facet: continue field, value = param_facet.split(":", 1) if value and field.split('_')[1] == 'exact': try: # Validate that the user belongs to the group if field.split('_')[0] == 'groups': InterestGroup.objects.\ filter(Q(memberships__user=self.request.user) | Q(owner=self.request.user)).\ get(slug=value) flag_group = True qs = qs.narrow('%s:"%s"' % (field, qs.query.clean(value))) except InterestGroup.DoesNotExist: # The user hasnt permissiont to filter by this group. pass self.facets = [] group_facet = get_facet_by_name(param_facet_url, qs.facet_counts()['fields'].items(), 'groups', self.request.user) if group_facet: self.facets.append(group_facet) order_by = self.request.query_params.get('order_by') if order_by: # TODO: Order by distance not found if order_by is 'distance': if distance and point: qs = qs.order_by(order_by) else: qs = qs.order_by(order_by) if not flag_group: qs = qs.narrow('%s:"%s"' % ('groups_exact', qs.query.clean('public'))) self.facets.append( get_facet_by_name(param_facet_url, qs.facet_counts()['fields'].items(), 'categories')) return qs
def get_combined(self, request, **kwargs): # tests self.method_check(request, allowed=['get']) #self.is_authenticated(request) self.throttle_check(request) # pagination limit = int(request.GET.get('limit', 20)) offset = int(request.GET.get('offset', 0)) page = (offset / limit) + 1 # Do the query q_args = {'published': request.GET.get('published', True), 'is_standalone': True} # add search query if 'q' in request.GET and request.GET['q'] != '': q_args['content'] = AutoQuery(remove_accents(request.GET['q'])) # check for more params params = ['category_id', 'category', 'user', 'user_id', 'is_active', 'id', 'featured', 'created__year', 'created__month', 'created__day', 'main_tag_id', 'follow_key', 'is_standalone'] for p in params: if p in request.GET: q_args[self.rename_get_filters.get(p, p)] = Exact(request.GET.get(p)) # check for additional date filters (with datetime objects) date_params = ['created__gt', 'created__lt'] for p in date_params: if p in request.GET: q_args[p] = models.DateTimeField().to_python(request.get(p)) # GET BY TAGS I FOLLOW if 'followed_by_tags' in request.GET: uid = int(request.GET['followed_by_tags']) follow_keys = ['tag.'+str(f.object_id) for f in Follow.objects.filter(content_type__model='tag', user__id=uid)] q_args['follow_key__in'] = follow_keys # show published and unpublished actions if q_args['published'] == 'all': del q_args['published'] # INIT THE QUERY sqs = SearchQuerySet().models(Campaign, Tag).load_all().filter(**q_args) # SPATIAL QUERY ADDONS # WITHIN QUERY if all(k in request.GET and request.GET.get(k) != '' for k in ('bottom_left', 'top_right')): bleft = [float(c) for c in request.GET.get('bottom_left').split(',')] bottom_left = Point(bleft[0], bleft[1]) tright = [float(c) for c in request.GET.get('top_right').split(',')] top_right = Point(tright[0], tright[1]) sqs = sqs.within('center', bottom_left, top_right) # DWITHIN QUERY if all(k in request.GET and request.GET.get(k) != '' for k in ('max_distance', 'center')): dist = Distance( m = int(request.GET.get('max_distance'))) pos = [float(c) for c in request.GET.get('center').split(',')] position = Point(pos[0], pos[1]) sqs = sqs.dwithin('center', position, dist) # ORDER BY order_by = request.GET.get('order_by', '-rank').split(',') # in elastic search 'score' is '_score' #order_by = [o if 'score' not in o else o.replace('score', '_score') for o in order_by] if 'q' in request.GET: if order_by == ['-rank'] and '-rank' not in request.GET: #order_by = ['_score'] order_by = ['score', '-rank'] # if q is set, then order will be search relevance first # if not, then do normal order by if 'distance' in order_by and 'center' in request.GET and request.GET['center'] != '': pos = [float(c) for c in request.GET.get('center').split(',')] position = Point(pos[0], pos[1]) sqs = sqs.distance('center', position).order_by(*order_by) elif len(order_by) > 0: sqs = sqs.order_by(*order_by) paginator = Paginator(sqs, limit) try: page = paginator.page(page) except InvalidPage: raise Http404("Sorry, no results on that page.") objects = [] for result in page.object_list: cache_key = result.model_name + '.' + str(result.obj_id) data = self._meta.cache.get(cache_key) if not data: bundle = resources[result.model_name].build_bundle(obj=result.object, request=request) bundle = resources[result.model_name].full_dehydrate(bundle) data = self._meta.cache.set(cache_key, bundle) objects.append(data) object_list = { 'meta': { 'limit': limit, 'next': page.has_next(), 'previous': page.has_previous(), 'total_count': sqs.count(), 'offset': offset }, 'objects': objects, } self.log_throttled_access(request) return self.create_response(request, object_list)
def searchresults(q=None, params=None, geo_location=None, geo_params=None, geo_orderby='distance', model_cls=None, default_filters=None, param_mappings=None, default_search_field='searchtext'): """Perform search leads using haystack""" print 'Eventsearch as Search' if not model_cls: model_cls = Postevent if params is None: params = OrderedDict([('festtype', None), ('city', None), ('festname', None), ('category', None), ('subcategory', None)]) # if orderby is None: # # orderby = 'created' # orderby = '-ispremium' # if geo_params is None: # geo_params = default_geo_params # if default_filters is None: # default_filters = default_lead_filters mappings = param_mappings or default_param_mappings sqs = SearchQuerySet().all() if q: print 'q1 in result', q qs = prepare_search_query(q, default_search_field) if qs: print 'qs in result', qs sqs = SearchQuerySet().filter(qs) print 'qs in resulted sqs', sqs sqs = sqs.models(model_cls) if params: sq_params = OrderedDict() for given_param, search_param in mappings.iteritems(): if has(params, given_param): sq_params[search_param] = params[given_param] if sq_params: print 'sqs in result', sqs sqs = sqs.filter(**sq_params) print "sqs with params", sqs # if orderby: # sqs = sqs.order_by(orderby) # if groupby: # sqs = sqs.facet(groupby) if geo_location: if isinstance(geo_location, (str, unicode)): country = geo_location elif isinstance(geo_location, (list, tuple)): country = geo_location else: location = geo_location if geo_params['method'] == 'bydistance': radius = D(km=geo_params['radius']) sqs = sqs.dwithin('geolocation', country, radius)\ .distance('geolocation', country) if geo_orderby: sqs = sqs.order_by('dista nce') print "Created query", unicode(sqs.query), geo_location, geo_params print "Created query", sqs return sqs