Skip to content

Commit

Permalink
fix: [NEWS] Filtered articles aren't retreived if they contain links -
Browse files Browse the repository at this point in the history
EXO-64780 (#895) (#902)

Prior to this change, when create an article with a link, open the news app, and filter articles by the keyword of the link, that article is not picked up in the filtered list. To fix this problem, add in the SQL query the search for this term in the property exo:body. After this change, this article is listed in the results.
  • Loading branch information
akhanfir authored Aug 7, 2023
1 parent 356b0f2 commit ce55902
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public class NewsSearchConnector extends SearchServiceConnector {

private static final Log LOG = ExoLogger.getLogger(NewsSearchConnector.class.getName());

private static final String FUZZY_SEARCH_SYNTAX = "~0.6";

public NewsSearchConnector(InitParams initParams,SessionProviderService sessionProviderService,RepositoryService repositoryService) throws Exception {
super(initParams);
Expand Down Expand Up @@ -60,9 +59,6 @@ public List<SearchResult> search(NewsFilter filter,
Session session = sessionProvider.getSession(repositoryService.getCurrentRepository().getConfiguration().getDefaultWorkspaceName(),
repositoryService.getCurrentRepository());

if (filter.getSearchText() != null) {
filter.setSearchText(this.addFuzzySyntaxAndOR(filter.getSearchText().trim().toLowerCase()));
}
List<SearchResult> res = new ArrayList<>();
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();
try {
Expand Down Expand Up @@ -93,35 +89,4 @@ public List<SearchResult> search(NewsFilter filter,
}
return res;
}

protected String addFuzzySyntaxAndOR(String text) {
StringBuilder fuzzyText = new StringBuilder();
boolean quote = false;
for (int i =0; i < text.length(); i++) {
if (text.charAt(i) == ' ' && text.charAt(i-1) != '"' && !quote) {
fuzzyText = fuzzyText.append(FUZZY_SEARCH_SYNTAX);
if(i != text.length()-1) {
fuzzyText = fuzzyText.append(" OR ");
}
} else if (text.charAt(i) == '"' && !quote){
fuzzyText = fuzzyText.append("\"");
quote = true;
} else if (text.charAt(i) == '"' && quote){
if (i != text.length()-1) {
quote = false;
fuzzyText = fuzzyText.append("\"").append(FUZZY_SEARCH_SYNTAX);
if(i != text.length()-1) {
fuzzyText = fuzzyText.append(" OR ");
}
} else {
quote = false;
fuzzyText = fuzzyText.append("\"");
}
}
else{
fuzzyText = fuzzyText.append(text.charAt(i));
}
}
return fuzzyText.append(FUZZY_SEARCH_SYNTAX).toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public class NewsQueryBuilder {

private final static String PLATFORM_WEB_CONTRIBUTORS_GROUP = "/platform/web-contributors";

private static final String FUZZY_SEARCH_SYNTAX = "~0.6";


/**
* builds query for news actions
*
Expand Down Expand Up @@ -53,8 +56,10 @@ public StringBuilder buildQuery(NewsFilter filter) throws Exception {
}
}
if (filter.getSearchText() != null && !filter.getSearchText().equals("")) {
String fuzzyText = this.addFuzzySyntaxAndOR(filter.getSearchText().trim().toLowerCase());
String escapedQuoteFuzzyText = fuzzyText.replace("'", "''").replace("\"", "\"\"");
String escapedQuoteSearchText = filter.getSearchText().replace("'", "''").replace("\"", "\"\"");
sqlQuery.append("CONTAINS(.,'").append(escapedQuoteSearchText).append("')");
sqlQuery.append("(CONTAINS(.,'").append(escapedQuoteFuzzyText).append("') OR (exo:body LIKE '%").append(escapedQuoteSearchText).append("%'))");
if (filter.getTagNames() != null && !filter.getTagNames().isEmpty()){
sqlQuery.append(" OR (");
for (String tagName : filter.getTagNames()) {
Expand Down Expand Up @@ -126,4 +131,35 @@ public StringBuilder buildQuery(NewsFilter filter) throws Exception {
}
return sqlQuery;
}

protected String addFuzzySyntaxAndOR(String text) {
StringBuilder fuzzyText = new StringBuilder();
boolean quote = false;
for (int i =0; i < text.length(); i++) {
if (text.charAt(i) == ' ' && text.charAt(i-1) != '"' && !quote) {
fuzzyText = fuzzyText.append(FUZZY_SEARCH_SYNTAX);
if(i != text.length()-1) {
fuzzyText = fuzzyText.append(" OR ");
}
} else if (text.charAt(i) == '"' && !quote){
fuzzyText = fuzzyText.append("\"");
quote = true;
} else if (text.charAt(i) == '"' && quote){
if (i != text.length()-1) {
quote = false;
fuzzyText = fuzzyText.append("\"").append(FUZZY_SEARCH_SYNTAX);
if(i != text.length()-1) {
fuzzyText = fuzzyText.append(" OR ");
}
} else {
quote = false;
fuzzyText = fuzzyText.append("\"");
}
}
else{
fuzzyText = fuzzyText.append(text.charAt(i));
}
}
return fuzzyText.append(FUZZY_SEARCH_SYNTAX).toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,110 +172,6 @@ public void shouldGetResultWhenNewsExists() throws Exception {
verify(rowIterator, times(1)).nextRow();
}

@Test
public void shouldAddFuzzySyntaxWhitQuotedWord() throws Exception {
// Given
String text = "\"quoted\"";
InitParams initParams = new InitParams();
PropertiesParam propertiesParam = new PropertiesParam();
Property searchTypeParam = new Property();
searchTypeParam.setName(searchType);
searchTypeParam.setValue("News");
Property displayNameParam = new Property();
displayNameParam.setName(displayName);
displayNameParam.setValue("News");
propertiesParam.setName("constructor.params");
propertiesParam.addProperty(searchTypeParam);
propertiesParam.addProperty(displayNameParam);
initParams.addParameter(propertiesParam);
NewsSearchConnector newsSearchConnector = new NewsSearchConnector(initParams, sessionProviderService, repositoryService);

// When
String result = newsSearchConnector.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "\"quoted\"~0.6");
}

@Test
public void shouldAddFuzzySyntaxWhenTextContainsMultiWords() throws Exception {
// Given
String text = "search text";
InitParams initParams = new InitParams();
PropertiesParam propertiesParam = new PropertiesParam();
Property searchTypeParam = new Property();
searchTypeParam.setName(searchType);
searchTypeParam.setValue("News");
Property displayNameParam = new Property();
displayNameParam.setName(displayName);
displayNameParam.setValue("News");
propertiesParam.setName("constructor.params");
propertiesParam.addProperty(searchTypeParam);
propertiesParam.addProperty(displayNameParam);
initParams.addParameter(propertiesParam);
NewsSearchConnector newsSearchConnector = new NewsSearchConnector(initParams, sessionProviderService, repositoryService);

// When
String result = newsSearchConnector.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "search~0.6 OR text~0.6");
}

@Test
public void shouldAddFuzzySyntaxWhenTextContainsQuotedMultiWords() throws Exception {
// Given
String text = "\"search text\"";
InitParams initParams = new InitParams();
PropertiesParam propertiesParam = new PropertiesParam();
Property searchTypeParam = new Property();
searchTypeParam.setName(searchType);
searchTypeParam.setValue("News");
Property displayNameParam = new Property();
displayNameParam.setName(displayName);
displayNameParam.setValue("News");
propertiesParam.setName("constructor.params");
propertiesParam.addProperty(searchTypeParam);
propertiesParam.addProperty(displayNameParam);
initParams.addParameter(propertiesParam);
NewsSearchConnector newsSearchConnector = new NewsSearchConnector(initParams, sessionProviderService, repositoryService);

// When
String result = newsSearchConnector.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "\"search text\"~0.6");
}

@Test
public void shouldAddFuzzySyntaxWhenTextContainsMultiWordsAndQuotedOne() throws Exception {
// Given
String text = "this is a \"search text\"";
InitParams initParams = new InitParams();
PropertiesParam propertiesParam = new PropertiesParam();
Property searchTypeParam = new Property();
searchTypeParam.setName(searchType);
searchTypeParam.setValue("News");
Property displayNameParam = new Property();
displayNameParam.setName(displayName);
displayNameParam.setValue("News");
propertiesParam.setName("constructor.params");
propertiesParam.addProperty(searchTypeParam);
propertiesParam.addProperty(displayNameParam);
initParams.addParameter(propertiesParam);
NewsSearchConnector newsSearchConnector = new NewsSearchConnector(initParams, sessionProviderService, repositoryService);

// When
String result = newsSearchConnector.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "this~0.6 OR is~0.6 OR a~0.6 OR \"search text\"~0.6");
}

@Test
public void shouldGetResultWhenSearchingWithQuery() throws Exception {
// Given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void shouldCreateQueryWithPinnedStateAndSearchTextAndAuthorAndOneSpaceAnd

// then
assertNotNull(query);
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND CONTAINS(.,'text') OR ( exo:body LIKE '%#text%' OR exo:body LIKE '%#tex%' ) AND exo:pinned = 'true' AND ( exo:spaceId = '1') AND exo:author = 'john' AND (publication:currentState = 'published' OR (publication:currentState = 'draft' AND exo:activities <> '' )) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY jcr:score DESC",
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND (CONTAINS(.,'text~0.6') OR (exo:body LIKE '%text%')) OR ( exo:body LIKE '%#text%' OR exo:body LIKE '%#tex%' ) AND exo:pinned = 'true' AND ( exo:spaceId = '1') AND exo:author = 'john' AND (publication:currentState = 'published' OR (publication:currentState = 'draft' AND exo:activities <> '' )) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY jcr:score DESC",
query.toString());
}

Expand All @@ -69,7 +69,6 @@ public void shouldCreateQueryWithPinnedStateAndAuthorAndSearchTextAndSpacesListA
filter.setSearchText("text");
filter.setOrder("jcr:score");
filter.setAuthor("john");
filter.setTagNames(Arrays.asList(new String[]{"text"}));
List<String> spaces = new ArrayList<>();
spaces.add("1");
spaces.add("2");
Expand All @@ -88,7 +87,7 @@ public void shouldCreateQueryWithPinnedStateAndAuthorAndSearchTextAndSpacesListA

// then
assertNotNull(query);
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND CONTAINS(.,'text') OR ( exo:body LIKE '%#text%' ) AND exo:pinned = 'true' AND ( exo:spaceId = '1' OR exo:spaceId = '2' OR exo:spaceId = '3') AND exo:author = 'john' AND (publication:currentState = 'published' OR (publication:currentState = 'draft' AND exo:activities <> '' )) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY jcr:score DESC",
assertEquals("SELECT * FROM exo:news WHERE ( exo:archived IS NULL OR exo:archived = 'false' OR ( exo:archived = 'true' AND exo:author = 'john')) AND (CONTAINS(.,'text~0.6') OR (exo:body LIKE '%text%'))AND exo:pinned = 'true' AND ( exo:spaceId = '1' OR exo:spaceId = '2' OR exo:spaceId = '3') AND exo:author = 'john' AND (publication:currentState = 'published' OR (publication:currentState = 'draft' AND exo:activities <> '' )) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY jcr:score DESC",
query.toString());
}

Expand Down Expand Up @@ -203,4 +202,74 @@ public void shouldCreateQueryWithStagedStateWhenCurrentUserIsAuthor() throws Exc
assertEquals("SELECT * FROM exo:news WHERE publication:currentState = 'staged' AND (exo:author = 'john' OR exo:spaceId = '1' OR exo:spaceId = '2' ) AND jcr:path LIKE '/Groups/spaces/%' ORDER BY null DESC",
query.toString());
}
@Test
public void shouldCreateQueryWithNoFilter() throws Exception {
// Given
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();
NewsFilter filter = new NewsFilter();
org.exoplatform.services.security.Identity currentIdentity = new org.exoplatform.services.security.Identity("john");
ConversationState state = new ConversationState(currentIdentity);
ConversationState.setCurrent(state);
filter = null;
// when
StringBuilder query = queryBuilder.buildQuery(filter);

// then
assertNotNull(query);
assertEquals("SELECT * FROM exo:news WHERE ", query.toString());
}
@Test
public void shouldAddFuzzySyntaxWhitQuotedWord() throws Exception {
// Given
String text = "\"quoted\"";
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();

// When
String result = queryBuilder.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "\"quoted\"~0.6");
}

@Test
public void shouldAddFuzzySyntaxWhenTextContainsMultiWords() throws Exception {
// Given
String text = "search text";
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();

// When
String result = queryBuilder.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "search~0.6 OR text~0.6");
}

@Test
public void shouldAddFuzzySyntaxWhenTextContainsQuotedMultiWords() throws Exception {
// Given
String text = "\"search text\"";
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();

// When
String result = queryBuilder.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "\"search text\"~0.6");
}
@Test
public void shouldAddFuzzySyntaxWhenTextContainsMultiWordsAndQuotedOne() throws Exception {
// Given
String text = "this is a \"search text\"";
NewsQueryBuilder queryBuilder = new NewsQueryBuilder();

// When
String result = queryBuilder.addFuzzySyntaxAndOR(text);

// Then
assertNotNull(result);
assertEquals(result, "this~0.6 OR is~0.6 OR a~0.6 OR \"search text\"~0.6");
}
}

0 comments on commit ce55902

Please sign in to comment.