Skip to content

Commit 7978150

Browse files
committed
Bug 1957309: Handle location signs as one of Yelp modifier
1 parent 21b2ede commit 7978150

File tree

5 files changed

+34
-87
lines changed

5 files changed

+34
-87
lines changed

components/suggest/src/db.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,11 +1354,6 @@ impl<'a> SuggestDao<'a> {
13541354
named_params! { ":record_id": record_id.as_str() },
13551355
)?;
13561356
self.scope.err_if_interrupted()?;
1357-
self.conn.execute_cached(
1358-
"DELETE FROM yelp_location_signs WHERE record_id = :record_id",
1359-
named_params! { ":record_id": record_id.as_str() },
1360-
)?;
1361-
self.scope.err_if_interrupted()?;
13621357
self.conn.execute_cached(
13631358
"DELETE FROM yelp_custom_details WHERE record_id = :record_id",
13641359
named_params! { ":record_id": record_id.as_str() },

components/suggest/src/rs.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ use serde_json::{Map, Value};
4242

4343
use crate::{error::Error, query::full_keywords_to_fts_content, Result};
4444

45+
use rusqlite::{types::ToSqlOutput, ToSql};
46+
4547
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4648
pub enum Collection {
4749
Amp,
@@ -453,12 +455,21 @@ pub(crate) struct DownloadedPocketSuggestion {
453455
pub high_confidence_keywords: Vec<String>,
454456
pub score: f64,
455457
}
456-
/// A location sign for Yelp to ingest from a Yelp Attachment
458+
/// Yelp location sign data type
457459
#[derive(Clone, Debug, Deserialize)]
458-
pub(crate) struct DownloadedYelpLocationSign {
459-
pub keyword: String,
460-
#[serde(rename = "needLocation")]
461-
pub need_location: bool,
460+
#[serde(untagged)]
461+
pub enum DownloadedYelpLocationSign {
462+
V1 { keyword: String },
463+
V2(String),
464+
}
465+
impl ToSql for DownloadedYelpLocationSign {
466+
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
467+
let keyword = match self {
468+
DownloadedYelpLocationSign::V1 { keyword } => keyword,
469+
DownloadedYelpLocationSign::V2(keyword) => keyword,
470+
};
471+
Ok(ToSqlOutput::from(keyword.as_str()))
472+
}
462473
}
463474
/// A Yelp suggestion to ingest from a Yelp Attachment
464475
#[derive(Clone, Debug, Deserialize)]

components/suggest/src/schema.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use sql_support::{
2323
/// `clear_database()` by adding their names to `conditional_tables`, unless
2424
/// they are cleared via a deletion trigger or there's some other good
2525
/// reason not to do so.
26-
pub const VERSION: u32 = 35;
26+
pub const VERSION: u32 = 36;
2727

2828
/// The current Suggest database schema.
2929
pub const SQL: &str = "
@@ -171,12 +171,6 @@ CREATE TABLE yelp_modifiers(
171171
PRIMARY KEY (type, keyword)
172172
) WITHOUT ROWID;
173173
174-
CREATE TABLE yelp_location_signs(
175-
keyword TEXT PRIMARY KEY,
176-
need_location INTEGER NOT NULL,
177-
record_id TEXT NOT NULL
178-
) WITHOUT ROWID;
179-
180174
CREATE TABLE yelp_custom_details(
181175
icon_id TEXT PRIMARY KEY,
182176
score REAL NOT NULL,
@@ -643,6 +637,10 @@ impl ConnectionInitializer for SuggestConnectionInitializer<'_> {
643637
)?;
644638
Ok(())
645639
}
640+
35 => {
641+
tx.execute_batch("DROP TABLE yelp_location_signs;")?;
642+
Ok(())
643+
}
646644
_ => Err(open_database::Error::IncompatibleVersion(version)),
647645
}
648646
}
@@ -660,7 +658,6 @@ pub fn clear_database(db: &Connection) -> rusqlite::Result<()> {
660658
DELETE FROM icons;
661659
DELETE FROM yelp_subjects;
662660
DELETE FROM yelp_modifiers;
663-
DELETE FROM yelp_location_signs;
664661
DELETE FROM yelp_custom_details;
665662
",
666663
)?;

components/suggest/src/testing/data.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,12 @@ pub fn ramen_yelp() -> JsonValue {
295295
"preModifiers": ["best", "super best", "same_modifier"],
296296
"postModifiers": ["delivery", "super delivery", "same_modifier"],
297297
"locationSigns": [
298+
// V1 format also can be used as location sign.
298299
{ "keyword": "in", "needLocation": true },
299-
{ "keyword": "near", "needLocation": true },
300300
{ "keyword": "near by", "needLocation": false },
301-
{ "keyword": "near me", "needLocation": false },
301+
// V2 format.
302+
"near",
303+
"near me",
302304
],
303305
"yelpModifiers": ["yelp", "yelp keyword"],
304306
"icon": "yelp-favicon",

components/suggest/src/yelp.rs

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum Modifier {
2222
Pre = 0,
2323
Post = 1,
2424
Yelp = 2,
25+
LocationSign = 3,
2526
}
2627

2728
impl ToSql for Modifier {
@@ -53,11 +54,6 @@ const MAX_QUERY_LENGTH: usize = 150;
5354
/// "keyword=:modifier" (please see is_modifier()), define this how many words we should check.
5455
const MAX_MODIFIER_WORDS_NUMBER: usize = 2;
5556

56-
/// The max number of words consisting the location sign. To improve the SQL performance by matching
57-
/// with "keyword=:modifier" (please see is_location_sign()), define this how many words we should
58-
/// check.
59-
const MAX_LOCATION_SIGN_WORDS_NUMBER: usize = 2;
60-
6157
/// At least this many characters must be typed for a subject to be matched.
6258
const SUBJECT_PREFIX_MATCH_THRESHOLD: usize = 2;
6359

@@ -115,14 +111,14 @@ impl SuggestDao<'_> {
115111
)?;
116112
}
117113

118-
for sign in &suggestion.location_signs {
114+
for keyword in &suggestion.location_signs {
119115
self.scope.err_if_interrupted()?;
120116
self.conn.execute_cached(
121-
"INSERT INTO yelp_location_signs(record_id, keyword, need_location) VALUES(:record_id, :keyword, :need_location)",
117+
"INSERT INTO yelp_modifiers(record_id, type, keyword) VALUES(:record_id, :type, :keyword)",
122118
named_params! {
123119
":record_id": record_id.as_str(),
124-
":keyword": sign.keyword,
125-
":need_location": sign.need_location,
120+
":type": Modifier::LocationSign,
121+
":keyword": keyword,
126122
},
127123
)?;
128124
}
@@ -178,7 +174,8 @@ impl SuggestDao<'_> {
178174
query_words = &query_words[n..];
179175
}
180176

181-
let location_sign_tuple = self.find_location_sign(query_words)?;
177+
let location_sign_tuple =
178+
self.find_modifier(query_words, Modifier::LocationSign, FindFrom::First)?;
182179
if let Some((_, n)) = location_sign_tuple {
183180
query_words = &query_words[n..];
184181
}
@@ -201,7 +198,6 @@ impl SuggestDao<'_> {
201198
subject_exact_match: subject_tuple.1,
202199
pre_modifier: pre_modifier_tuple.map(|(words, _)| words.to_string()),
203200
post_modifier: post_modifier_tuple.map(|(words, _)| words.to_string()),
204-
need_location: location_sign_tuple.is_some() || location.is_some(),
205201
location_sign: location_sign_tuple.map(|(words, _)| words.to_string()),
206202
location,
207203
icon,
@@ -327,52 +323,6 @@ impl SuggestDao<'_> {
327323
Ok(None)
328324
}
329325

330-
/// Find the location sign for given query.
331-
/// It returns Option<tuple> as follows:
332-
/// (
333-
/// String: The keyword in DB (but the case is inherited by query).
334-
/// usize: Number of words in query_words that match the keyword.
335-
/// Maximum number is MAX_LOCATION_SIGN_WORDS_NUMBER.
336-
/// )
337-
fn find_location_sign(&self, query_words: &[&str]) -> Result<Option<(String, usize)>> {
338-
if query_words.is_empty() {
339-
return Ok(None);
340-
}
341-
342-
for n in (1..=std::cmp::min(MAX_LOCATION_SIGN_WORDS_NUMBER, query_words.len())).rev() {
343-
let mut candidate_chunk = query_words.chunks(n);
344-
let candidate = candidate_chunk
345-
.next()
346-
.map(|chunk| chunk.join(" "))
347-
.unwrap_or_default();
348-
if let Some(keyword_lowercase) = self.conn.try_query_one::<String, _>(
349-
if n == query_words.len() {
350-
"
351-
SELECT keyword FROM yelp_location_signs
352-
WHERE keyword BETWEEN :word AND :word || x'FFFF'
353-
LIMIT 1
354-
"
355-
} else {
356-
"
357-
SELECT keyword FROM yelp_location_signs
358-
WHERE keyword = :word
359-
LIMIT 1
360-
"
361-
},
362-
named_params! {
363-
":word": candidate.to_lowercase(),
364-
},
365-
true,
366-
)? {
367-
// Preserve the query as the user typed it including its case.
368-
let keyword = format!("{}{}", candidate, &keyword_lowercase[candidate.len()..]);
369-
return Ok(Some((keyword, n)));
370-
}
371-
}
372-
373-
Ok(None)
374-
}
375-
376326
/// Fetch the custom details for Yelp suggestions.
377327
/// It returns the location tuple as follows:
378328
/// (
@@ -421,25 +371,17 @@ struct SuggestionBuilder<'a> {
421371
post_modifier: Option<String>,
422372
location_sign: Option<String>,
423373
location: Option<String>,
424-
need_location: bool,
425374
icon: Option<Vec<u8>>,
426375
icon_mimetype: Option<String>,
427376
score: f64,
428377
}
429378

430379
impl<'a> From<SuggestionBuilder<'a>> for Suggestion {
431380
fn from(builder: SuggestionBuilder<'a>) -> Suggestion {
432-
// This location sign such the 'near by' needs to add as a description parameter.
433-
let location_modifier = if !builder.need_location {
434-
builder.location_sign.as_deref()
435-
} else {
436-
None
437-
};
438381
let description = [
439382
builder.pre_modifier.as_deref(),
440383
Some(builder.subject),
441384
builder.post_modifier.as_deref(),
442-
location_modifier,
443385
]
444386
.iter()
445387
.flatten()
@@ -451,7 +393,7 @@ impl<'a> From<SuggestionBuilder<'a>> for Suggestion {
451393
let mut url = String::from("https://www.yelp.com/search?");
452394
let mut parameters = form_urlencoded::Serializer::new(String::new());
453395
parameters.append_pair("find_desc", &description);
454-
if let (Some(location), true) = (&builder.location, builder.need_location) {
396+
if let Some(location) = &builder.location {
455397
parameters.append_pair("find_loc", location);
456398
}
457399
url.push_str(&parameters.finish());
@@ -475,7 +417,7 @@ impl<'a> From<SuggestionBuilder<'a>> for Suggestion {
475417
icon: builder.icon,
476418
icon_mimetype: builder.icon_mimetype,
477419
score: builder.score,
478-
has_location_sign: location_modifier.is_none() && builder.location_sign.is_some(),
420+
has_location_sign: builder.location_sign.is_some(),
479421
subject_exact_match: builder.subject_exact_match,
480422
location_param: "find_loc".to_string(),
481423
}

0 commit comments

Comments
 (0)