package service import ( "fmt" "log" "net/url" "time" "errors" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "xiaoniaokuaiyan.com/xiaoniao/config" "xiaoniaokuaiyan.com/xiaoniao/search" ) type SearchService struct{} var ( mgoSess *mgo.Session ) func getMgoDB() *mgo.Database { var ( mgoURI = config.IniConf.Section("database").Key("mgo.uri").Value() mgoDatabase = config.IniConf.Section("database").Key("mgo.database").Value() mgoUser = config.IniConf.Section("database").Key("mgo.user").Value() mgoPassword = config.IniConf.Section("database").Key("mgo.password").Value() ) mgoURI = fmt.Sprintf("%s:%s@%s/%s", mgoUser, url.QueryEscape(mgoPassword), mgoURI, mgoDatabase) var err error if mgoSess == nil { mgoSess, err = mgo.Dial(mgoURI) if err != nil { log.Println(err) return nil } } return mgoSess.Copy().DB(mgoDatabase) } func (srv *SearchService) Query(param *search.QueryParam, uid int) (interface{}, error) { go func() { db := getMgoDB() if db == nil { return } defer db.Session.Close() /*var targetObj = bson.M{} err := db.C("search_history").Find(bson.M{ "user_id": uid, "text": text, }).One(targetObj) if err != nil && err != mgo.ErrNotFound { fmt.Println(err) } else { if num, ok := targetObj["num"]; !ok { db.C("search_product").Insert(bson.M{ "_id": cityId, "text": text, "num": 1, }) } else { db.C("search_product").Upsert(bson.M{ "city_id": cityId, "text": text, }, bson.M{"$set": bson.M{"num": num.(int) + 1}}) } }*/ err := db.C("search_text_log").Insert(bson.M{ "city_id": param.CityId, "text": param.Text, "user_id": uid, "created_at": time.Now().Format("2006-01-02 15:04:05"), }) if err != nil { fmt.Println(err) return } }() return search.Query(param) } func (srv *SearchService) GetTip(text string, cityId int, isZFB bool) (interface{}, error) { return search.GetSearchTips(text, cityId, isZFB) } func (srv *SearchService) GetTopKeyword(cityId int, sn int) (interface{}, error) { if sn > 20 { sn = 20 } if sn == 0 { sn = 10 } var querySelector interface{} = bson.M{} if cityId > 0 { querySelector = bson.M{ "city_id": cityId, } } return getTopKeyword(querySelector, sn) } func (srv *SearchService) GetUserKeyword(uid int, sn int) (interface{}, error) { if uid < 0 { return nil, errors.New("1::user id is required") } if sn > 20 { sn = 20 } if sn == 0 { sn = 10 } var querySelector = bson.M{ "user_id": uid, "text": bson.M{"$ne": ""}, } db := getMgoDB() defer db.Session.Close() var pipes = []bson.M{ bson.M{ "$match": querySelector, }, bson.M{ "$sort": bson.M{ "created_at": -1, }, }, bson.M{ "$group": bson.M{ "_id": "$text", "created_at": bson.M{ "$max": "$created_at", }, }, }, bson.M{ "$sort": bson.M{ "created_at": -1, }, }, bson.M{ "$project": bson.M{"_id": 0, "text": "$_id"}, }, bson.M{ "$limit": sn, }, } keywords := []bson.M{} err := db.C("search_text_log").Pipe(pipes).All(&keywords) //Find(querySelector).Select(bson.M{"text": 1, "_id": 0}).Sort("-created_at").Limit(sn).All(&keywords) return keywords, err } func getTopKeyword(querySelector interface{}, size int) ([]bson.M, error) { db := getMgoDB() defer db.Session.Close() keywords := []bson.M{} var pipes = []bson.M{ bson.M{ "$match": querySelector, }, bson.M{ "$group": bson.M{ "_id": "$text", "count": bson.M{ "$sum": 1, }, }, }, bson.M{ "$sort": bson.M{ "count": -1, }, }, bson.M{ "$project": bson.M{"_id": 0, "text": "$_id"}, }, bson.M{ "$limit": size, }, } err := db.C("search_text_log").Pipe(pipes).All(&keywords) //.Find(querySelector).Select(bson.M{"text": 1, "_id": 0}).Sort("-num").Limit(sn).All(&keywords) return keywords, err }