Skip to content

Commit f07dfad

Browse files
Abdelrahman-358Abdelrahman MostafaSiedlerchr
authored
Fix inconsistent search results for date-related queries fixes#12296 (#12724)
* fixed date bug * Fix inconsistent search results when querying different date fields (date, Date, year) * Rename functions * Updated CHANGELOG.md * Fix date-related query issues fixes #12296 * Fixes 12296 * Fix for issue 12296 * Added java comments * Fixed submodules * Updated dateFields * Removed unnecessary comment. * Update src/main/java/org/jabref/logic/search/indexing/BibFieldsIndexer.java Co-authored-by: Christoph <[email protected]> * fixed compilation error * fix npe when switching tabs and entry is null --------- Co-authored-by: Abdelrahman Mostafa <[email protected]> Co-authored-by: Christoph <[email protected]>
1 parent 87984c3 commit f07dfad

File tree

5 files changed

+61
-16
lines changed

5 files changed

+61
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
101101
- We fixed an issue where JabRef displayed an incorrect deletion notification when canceling entry deletion. [#12645](https://github.com/JabRef/jabref/issues/12645)
102102
- We fixed an issue where JabRref wrote wrong field names into the PDF. [#12833](https://github.com/JabRef/jabref/pulls/12833)
103103
- We fixed an issue where an exception would occur when running abbreviate journals for multiple entries. [#12634](https://github.com/JabRef/jabref/issues/12634)
104+
- We fixed an issue Where JabRef displayed an inconsistent search results for date-related queries[#12296](https://github.com/JabRef/jabref/issues/12296)
104105
- We fixed an issue where JabRef displayed dropdown triangle in wrong place in "Search for unlinked local files" dialog [#12713](https://github.com/JabRef/jabref/issues/12713)
105106
- We fixed an issue where JabRef would not open if an invalid external journal abbreviation path was encountered. [#12776](https://github.com/JabRef/jabref/issues/12776)
106107
- We fixed a bug where LaTeX commands were not removed from filenames generated using the `[bibtexkey] - [fulltitle]` pattern. [#12188](https://github.com/JabRef/jabref/issues/12188)

src/main/java/org/jabref/gui/entryeditor/fileannotationtab/FulltextSearchResultsTab.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private void updateSearch() {
9494
content.getChildren().clear();
9595
stateManager.activeSearchQuery(SearchType.NORMAL_SEARCH).get().ifPresent(searchQuery -> {
9696
SearchResults searchResults = searchQuery.getSearchResults();
97-
if (searchResults != null) {
97+
if (searchResults != null && entry != null) {
9898
Map<String, List<SearchResult>> searchResultsForEntry = searchResults.getFileSearchResultsForEntry(entry);
9999
if (searchResultsForEntry.isEmpty()) {
100100
content.getChildren().add(new Text(Localization.lang("No search matches.")));

src/main/java/org/jabref/logic/search/indexing/BibFieldsIndexer.java

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.Collection;
88
import java.util.Map;
99
import java.util.Optional;
10+
import java.util.Set;
1011
import java.util.regex.Pattern;
1112

1213
import org.jabref.logic.l10n.Localization;
@@ -38,6 +39,7 @@ public class BibFieldsIndexer {
3839
private static final Logger LOGGER = LoggerFactory.getLogger(BibFieldsIndexer.class);
3940
private static final LatexToUnicodeFormatter LATEX_TO_UNICODE_FORMATTER = new LatexToUnicodeFormatter();
4041
private static final Pattern GROUPS_SEPARATOR_REGEX = Pattern.compile("\s*,\s*");
42+
private static final Set<Field> DATE_FIELDS = Set.of(StandardField.DATE, StandardField.YEAR, StandardField.MONTH, StandardField.DAY);
4143

4244
private final BibDatabaseContext databaseContext;
4345
private final Connection connection;
@@ -215,10 +217,12 @@ private void addToIndex(BibEntry bibEntry) {
215217
// We add a `.orElse("")` only because there could be some flaw in the future in the code - and we want to have search working even if the flaws are present.
216218
// To uncover these flaws, we add the "assert" statement.
217219
// One potential future flaw is that the bibEntry is modified concurrently and the field being deleted.
218-
Optional<String> resolvedFieldLatexFree = bibEntry.getResolvedFieldOrAliasLatexFree(field, this.databaseContext.getDatabase());
219-
assert resolvedFieldLatexFree.isPresent();
220-
addBatch(preparedStatement, entryId, field, value, resolvedFieldLatexFree.orElse(""));
221-
220+
// Skip indexing of date-related fields separately to ensure proper handling later in the process.
221+
if (!DATE_FIELDS.contains(field)) {
222+
Optional<String> resolvedFieldLatexFree = bibEntry.getResolvedFieldOrAliasLatexFree(field, this.databaseContext.getDatabase());
223+
assert resolvedFieldLatexFree.isPresent();
224+
addBatch(preparedStatement, entryId, field, value, resolvedFieldLatexFree.orElse(""));
225+
}
222226
// region Handling of known multi-value fields
223227
// split and convert to Unicode
224228
if (field.getProperties().contains(FieldProperty.PERSON_NAMES)) {
@@ -239,7 +243,11 @@ private void addToIndex(BibEntry bibEntry) {
239243
}
240244
// endregion
241245
}
242-
246+
// ensure all date-related fields are indexed.
247+
for (Field dateField : DATE_FIELDS) {
248+
Optional<String> resolvedDateValue = bibEntry.getResolvedFieldOrAlias(dateField, this.databaseContext.getDatabase());
249+
resolvedDateValue.ifPresent(dateValue -> addBatch(preparedStatement, entryId, dateField, dateValue));
250+
}
243251
// add entry type
244252
addBatch(preparedStatement, entryId, TYPE_HEADER, bibEntry.getType().getName());
245253

@@ -302,16 +310,46 @@ private void insertField(BibEntry entry, Field field) {
302310
FIELD_VALUE_LITERAL,
303311
FIELD_VALUE_TRANSFORMED);
304312

305-
try (PreparedStatement preparedStatement = connection.prepareStatement(insertFieldQuery)) {
306-
String entryId = entry.getId();
307-
String value = entry.getField(field).orElse("");
313+
// Inserts or updates date-related fields (e.g., date, year, month, day) into the index.
314+
// If a conflict occurs (e.g., the same ENTRY_ID and FIELD_NAME already exist),
315+
// the existing values are overwritten with the new ones to ensure the latest data is stored.
316+
String insertDateFieldQuery = """
317+
INSERT INTO %s ("%s", "%s", "%s", "%s")
318+
VALUES (?, ?, ?, ?)
319+
ON CONFLICT ("%s", "%s")
320+
DO UPDATE SET "%s" = EXCLUDED."%s", "%s" = EXCLUDED."%s"
321+
""".formatted(
322+
schemaMainTableReference,
323+
ENTRY_ID,
324+
FIELD_NAME,
325+
FIELD_VALUE_LITERAL,
326+
FIELD_VALUE_TRANSFORMED,
327+
ENTRY_ID, FIELD_NAME,
328+
FIELD_VALUE_LITERAL, FIELD_VALUE_LITERAL,
329+
FIELD_VALUE_TRANSFORMED, FIELD_VALUE_TRANSFORMED);
330+
331+
String entryId = entry.getId();
332+
if (DATE_FIELDS.contains(field)) {
333+
try (PreparedStatement preparedStatement = connection.prepareStatement(insertDateFieldQuery)) {
334+
for (Field dateField : DATE_FIELDS) {
335+
Optional<String> resolvedDateValue = entry.getResolvedFieldOrAlias(dateField, this.databaseContext.getDatabase());
336+
resolvedDateValue.ifPresent(dateValue -> addBatch(preparedStatement, entryId, dateField, dateValue));
337+
}
338+
preparedStatement.executeBatch();
339+
} catch (SQLException e) {
340+
LOGGER.error("Could not add an entry to the index.", e);
341+
}
342+
} else {
343+
try (PreparedStatement preparedStatement = connection.prepareStatement(insertFieldQuery)) {
344+
String value = entry.getField(field).orElse("");
308345

309-
Optional<String> resolvedFieldLatexFree = entry.getResolvedFieldOrAliasLatexFree(field, this.databaseContext.getDatabase());
310-
assert resolvedFieldLatexFree.isPresent();
311-
addBatch(preparedStatement, entryId, field, value, resolvedFieldLatexFree.orElse(""));
312-
preparedStatement.executeBatch();
313-
} catch (SQLException e) {
314-
LOGGER.error("Could not add an entry to the index.", e);
346+
Optional<String> resolvedFieldLatexFree = entry.getResolvedFieldOrAliasLatexFree(field, this.databaseContext.getDatabase());
347+
assert resolvedFieldLatexFree.isPresent();
348+
addBatch(preparedStatement, entryId, field, value, resolvedFieldLatexFree.orElse(""));
349+
preparedStatement.executeBatch();
350+
} catch (SQLException e) {
351+
LOGGER.error("Could not add an entry to the index.", e);
352+
}
315353
}
316354

317355
String insertIntoSplitTable = """
@@ -325,7 +363,6 @@ private void insertField(BibEntry entry, Field field) {
325363
FIELD_VALUE_TRANSFORMED);
326364

327365
try (PreparedStatement preparedStatement = connection.prepareStatement(insertIntoSplitTable)) {
328-
String entryId = entry.getId();
329366
String value = entry.getField(field).orElse("");
330367

331368
if (field.getProperties().contains(FieldProperty.PERSON_NAMES)) {

src/main/java/org/jabref/model/entry/LinkedFile.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.io.ObjectInputStream;
55
import java.io.ObjectOutputStream;
6+
import java.io.Serial;
67
import java.io.Serializable;
78
import java.net.URL;
89
import java.nio.file.Files;
@@ -170,6 +171,7 @@ public boolean equals(@Nullable Object o) {
170171
/**
171172
* Writes serialized object to ObjectOutputStream, automatically called
172173
*/
174+
@Serial
173175
private void writeObject(ObjectOutputStream out) throws IOException {
174176
out.writeUTF(getFileType());
175177
out.writeUTF(getLink());
@@ -181,6 +183,7 @@ private void writeObject(ObjectOutputStream out) throws IOException {
181183
/**
182184
* Reads serialized object from {@link ObjectInputStream}, automatically called
183185
*/
186+
@Serial
184187
private void readObject(ObjectInputStream in) throws IOException {
185188
fileType = new SimpleStringProperty(in.readUTF());
186189
link = new SimpleStringProperty(in.readUTF());

src/main/java/org/jabref/model/search/PostgreConstants.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public static String getMainTableSchemaReference(String mainTable) {
6363
return BIB_FIELDS_SCHEME + ".\"" + mainTable + "\"";
6464
}
6565

66+
/**
67+
* Generates the schema reference for the split table, which is used to store multi-value fields (e.g., authors, keywords)
68+
* in a normalized form to facilitate efficient querying and indexing of the data.
69+
*/
6670
public static String getSplitTableSchemaReference(String mainTable) {
6771
return BIB_FIELDS_SCHEME + ".\"" + mainTable + SPLIT_TABLE_SUFFIX + "\"";
6872
}

0 commit comments

Comments
 (0)