Example #1
0
func (r *RestApi) users(w http.ResponseWriter, req *http.Request) {
	field := req.URL.Query().Get("field")
	query := req.URL.Query().Get("query")
	distance := req.URL.Query().Get("distance")
	latStr := req.URL.Query().Get("lat")
	lonStr := req.URL.Query().Get("lon")
	size := req.URL.Query().Get("l")
	skip := req.URL.Query().Get("s")
	wildcard := req.URL.Query().Get("w")

	sizeInt, err := strconv.Atoi(size)
	if err != nil {
		sizeInt = 100
	}

	skipInt, err := strconv.Atoi(skip)
	if err != nil {
		skipInt = 0
	}

	if field == "" {
		field = "_all"
	}

	if query == "" && distance == "" {
		fmt.Fprintf(w, "Query and Distance can't be empty!")
		return
	}

	var elasticQuery elastic.Query
	var long, lat float64
	if distance != "" {
		long, err = strconv.ParseFloat(lonStr, 64)
		if err != nil {
			fmt.Fprintf(w, "Longitude can't be empty!")
			return
		}

		lat, err = strconv.ParseFloat(latStr, 64)
		if err != nil {
			fmt.Fprintf(w, "Latitude can't be empty!")
			return
		}

		log.Infof("Start searching for users in distance: %s from (lat, lng): (%f, %f)", distance, lat, long)

		// Search with a geo query
		geoQuery := elastic.NewGeoDistanceFilter("location").Distance(distance + "km").Lat(lat).Lon(long)
		elasticQuery = elastic.NewFilteredQuery(elastic.NewMatchAllQuery()).Filter(geoQuery)
	} else {
		log.Infof("Start searching for users: %s", query)

		if wildcard == "true" {
			// Search for
			elasticQuery = elastic.NewSimpleQueryStringQuery(query).Field(field)
		} else {
			// Search with a term query
			elasticQuery = elastic.NewMatchQuery(field, query)
		}

	}

	searchResult, err := r.e.Search().
		Index("users").
		Type("user").
		Query(elasticQuery).
		From(skipInt).Size(sizeInt).
		Do()
	if err != nil {
		fmt.Fprintf(w, "Can't search for users. Err: %v", err)
		return
	}

	response := UsersResponse{}

	// Here's how you iterate through results with full control over each step.
	if searchResult.Hits != nil {
		log.Printf("Found a total of %d users", searchResult.Hits.TotalHits)

		response.Total = searchResult.Hits.TotalHits

		// Iterate through results
		for _, hit := range searchResult.Hits.Hits {
			var u models.User
			err := json.Unmarshal(*hit.Source, &u)
			if err != nil {
				fmt.Fprintf(w, "Can't deserialize user. Err: %v", err)
				return
			}

			u.Score = hit.Score

			response.Users = append(response.Users, u)
			log.Infof("Found user %v", u.Email)
		}
	} else {
		fmt.Fprintf(w, "Found no users")
		return
	}

	json, err := json.Marshal(response)
	if err != nil {
		fmt.Fprintf(w, "Can't serialize users. Err: %v", err)
		return
	}

	w.Write(json)
}