Skip to content

Commit b9e14ca

Browse files
committed
Added search.js , fixed issue #2.
1 parent b0c1915 commit b9e14ca

File tree

3 files changed

+242
-1
lines changed

3 files changed

+242
-1
lines changed

gulpfile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ var coreSources = [
3030
'query.js',
3131
'cloudfunction.js',
3232
'push.js',
33-
'status.js'
33+
'status.js',
34+
'search.js'
3435
];
3536

3637
var optionalSources = [

lib/av.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ var include = function(filename) {
4444
'cloudfunction.js',
4545
'push.js',
4646
'status.js',
47+
'search.js'
4748
].forEach(include);

lib/search.js

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
(function(root) {
2+
root.AV = root.AV || {};
3+
var AV = root.AV;
4+
var _ = AV._;
5+
6+
/**
7+
* A builder to generate sort string for app searching.
8+
* @class
9+
*/
10+
AV.SearchSortBuilder = function() {
11+
this._sortFields = [];
12+
};
13+
14+
AV.SearchSortBuilder.prototype = {
15+
_addField: function(key, order, mode, missing) {
16+
var field = {};
17+
field[key] = {
18+
order: order || 'asc',
19+
mode: mode ||'avg',
20+
missing: '_' + (missing || 'last')
21+
};
22+
this._sortFields.push(field);
23+
return this;
24+
},
25+
26+
27+
/**
28+
* Sorts the results in ascending order by the given key and options.
29+
*
30+
* @param {String} key The key to order by.
31+
* @param {String} mode The sort mode, default is 'avg', you can choose
32+
* 'max' or 'min' too.
33+
* @param {String} missing The missing key behaviour, default is 'last',
34+
* you can choose 'first' too.
35+
* @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.
36+
*/
37+
ascending: function(key, mode, missing) {
38+
return this._addField(key, 'asc', mode, missing);
39+
},
40+
41+
/**
42+
* Sorts the results in descending order by the given key and options.
43+
*
44+
* @param {String} key The key to order by.
45+
* @param {String} mode The sort mode, default is 'avg', you can choose
46+
* 'max' or 'min' too.
47+
* @param {String} missing The missing key behaviour, default is 'last',
48+
* you can choose 'first' too.
49+
* @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.
50+
*/
51+
descending: function(key, mode, missing) {
52+
return this._addField(key, 'desc', mode, missing);
53+
},
54+
55+
/**
56+
* Add a proximity based constraint for finding objects with key point
57+
* values near the point given.
58+
* @param {String} key The key that the AV.GeoPoint is stored in.
59+
* @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.
60+
* @param {Object} options The other options such as mode,order, unit etc.
61+
* @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.
62+
*/
63+
whereNear: function(key, point, options) {
64+
options = options || {};
65+
var field = {};
66+
var geo = {
67+
lat: point.latitude,
68+
lon: point.longitude
69+
};
70+
var m = {
71+
order: options.order || 'asc',
72+
mode: options.mode || 'avg',
73+
unit: options.unit || 'km'
74+
};
75+
m[key] = geo;
76+
field['_geo_distance'] = m;
77+
78+
this._sortFields.push(field);
79+
return this;
80+
},
81+
82+
/**
83+
* Build a sort string by configuration.
84+
* @return {String} the sort string.
85+
*/
86+
build: function() {
87+
return JSON.stringify(this._sortFields);
88+
}
89+
};
90+
91+
/**
92+
* App searching query.Use just like AV.Query:
93+
* <pre><code>
94+
* var query = new AV.SearchQuery('Player');
95+
* query.queryString('*');
96+
* query.find().then(function(results) {
97+
* console.log('Found %d objects', query.hits());
98+
* //Process results
99+
* });
100+
*
101+
* </code></pre>
102+
* Visite <a href='https://leancloud.cn/docs/app_search_guide.html>App Searching Guide</a>
103+
* for more details.
104+
* @class
105+
* @since 0.5.1
106+
*
107+
*/
108+
AV.SearchQuery = AV.Query._extend(/** @lends AV.InboxQuery.prototype */{
109+
_sid: null,
110+
_hits: 0,
111+
_queryString: null,
112+
_highlights: null,
113+
_sortBuilder: null,
114+
_createRequest: function(params){
115+
return AV._request("search/select", null, null, "GET",
116+
params || this.toJSON());
117+
},
118+
119+
/**
120+
* Sets the sid of app searching query.Default is null.
121+
* @param {String} sid Scroll id for searching.
122+
* @return {AV.SearchQuery} Returns the query, so you can chain this call.
123+
*/
124+
sid: function(sid) {
125+
this._sid = sid;
126+
return this;
127+
},
128+
129+
/**
130+
* Sets the query string of app searching.
131+
* @param {String} q The query string.
132+
* @return {AV.SearchQuery} Returns the query, so you can chain this call.
133+
*/
134+
queryString: function(q) {
135+
this._queryString = q;
136+
return this;
137+
},
138+
139+
140+
/**
141+
* Sets the highlight fields. Such as
142+
* <pre><code>
143+
* query.highlights('title');
144+
* //or pass an array.
145+
* query.highlights(['title', 'content'])
146+
* </code></pre>
147+
* @param {Array} highlights a list of fields.
148+
* @return {AV.SearchQuery} Returns the query, so you can chain this call.
149+
*/
150+
highlights: function(highlights) {
151+
var objects;
152+
if (highlights && AV._isNullOrUndefined(highlights.length)) {
153+
objects = arguments;
154+
} else {
155+
objects = highlights;
156+
}
157+
this._highlights = objects;
158+
return this;
159+
},
160+
161+
/**
162+
* Sets the sort builder for this query.
163+
* @see AV.SearchSortBuilder
164+
* @param { AV.SearchSortBuilder} builder The sort builder.
165+
* @return {AV.SearchQuery} Returns the query, so you can chain this call.
166+
*
167+
*/
168+
sortBy: function(builder) {
169+
this._sortBuilder = builder;
170+
return this;
171+
},
172+
173+
_processResult: function(json){
174+
delete json['className'];
175+
delete json['_app_url'];
176+
delete json['_deeplink'];
177+
return json;
178+
},
179+
180+
/**
181+
* Retrieves a list of AVObjects that satisfy this query.
182+
* Either options.success or options.error is called when the find
183+
* completes.
184+
*
185+
* @see AV.Query#find
186+
* @param {Object} options A Backbone-style options object.
187+
* @return {AV.Promise} A promise that is resolved with the results when
188+
* the query completes.
189+
*/
190+
find: function(options) {
191+
var self = this;
192+
193+
var request = this._createRequest();
194+
195+
return request.then(function(response) {
196+
//update sid for next querying.
197+
if(response.sid) {
198+
self._oldSid = self._sid;
199+
self._sid = response.sid;
200+
}
201+
self._hits = response.hits || 0;
202+
203+
return _.map(response.results, function(json) {
204+
if(json.className) {
205+
response.className = json.className;
206+
}
207+
var obj = self._newObject(response);
208+
obj.appURL = json['_app_url'];
209+
obj._finishFetch(self._processResult(json), true);
210+
return obj;
211+
});
212+
})._thenRunCallbacks(options);
213+
},
214+
215+
toJSON: function(){
216+
var params = AV.SearchQuery.__super__.toJSON.call(this);
217+
delete params.where;
218+
if(this._sid) {
219+
params.sid = this._sid;
220+
}
221+
if(!this._queryString) {
222+
throw 'Please set query string.';
223+
} else {
224+
params.q = this._queryString;
225+
}
226+
if(this._highlights) {
227+
params.highlights = this._highlights.join(',');
228+
}
229+
if(this._sortBuilder && params.order) {
230+
throw 'sort and order can not be set at same time.';
231+
}
232+
if(this._sortBuilder) {
233+
params.sort = this._sortBuilder.build();
234+
}
235+
236+
return params;
237+
}
238+
});
239+
})(this);

0 commit comments

Comments
 (0)