Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Library Management

Notices

Reply
 
Thread Tools Search this Thread
Old Yesterday, 02:36 AM   #1
Montana Harper
Zealot
Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.Montana Harper ought to be getting tired of karma fortunes by now.
 
Montana Harper's Avatar
 
Posts: 106
Karma: 2029154
Join Date: Sep 2013
Location: Pacific Northwest
Device: iPad Mini, iPhone 12, Kindle Paperwhite 3
Template to search notes?

I realize this is probably a really niche thing, but is there any way to search a notes field (e.g., notes attached to an author) for specific text? I want to build a custom column that shows me a check mark if particular text is included in an author note.

I have a number of custom columns built from other columns that do something similar, but since the notes aren't fields with lookup names, I'm not even sure if it's possible to do what I want. Currently I'm using a workaround that involves adding a specific tag to every book by an author whom I want to flag, but that's both time-consuming and easy to forget about when adding a new book, whereas if I can just make a single note for the author it would be so much easier.

TIA!
Montana Harper is offline   Reply With Quote
Old Yesterday, 04:31 AM   #2
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,123
Karma: 6426808
Join Date: Sep 2020
Device: Calibre E-book viewer
Quote:
Originally Posted by Montana Harper View Post
I realize this is probably a really niche thing, but is there any way to search a notes field (e.g., notes attached to an author) for specific text? I want to build a custom column that shows me a check mark if particular text is included in an author note.
I'd be interested in that, as well.

Currently the way I see to do it is using the Notes Browser with its FTS-like search syntax, like this:

Click image for larger version

Name:	MWSnap 2024-09-12, 05_02_49.png
Views:	25
Size:	58.1 KB
ID:	210786

In that example I've searched for authors born in 9/11.

Default shortcut is Ctrl + Shift + N. However I can't tell how to bring all results from that search into "main Calibre", so that I could bulk add the "Born in 9/11" tag, for instance.
Comfy.n is offline   Reply With Quote
Old Yesterday, 06:49 AM   #3
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by Montana Harper View Post
I realize this is probably a really niche thing, but is there any way to search a notes field (e.g., notes attached to an author) for specific text? I want to build a custom column that shows me a check mark if particular text is included in an author note.

I have a number of custom columns built from other columns that do something similar, but since the notes aren't fields with lookup names, I'm not even sure if it's possible to do what I want. Currently I'm using a workaround that involves adding a specific tag to every book by an author whom I want to flag, but that's both time-consuming and easy to forget about when adding a new book, whereas if I can just make a single note for the author it would be so much easier.

TIA!
You can do this with the template function get_note().

You can search a note using a template like this one, suitably modified.
Code:
program:
	first_author = sublist($authors, 0, 1, '&');
	note = get_note('authors', first_author, '1');
	if 'something' in note then
		ans = 'Yes'
	else
		ans = 'No'
	fi;
	ans
Notes on the template:
  • This uses the first author. You must decide what to do if there are multiple authors. For example, you might want to loop over all the authors checking if any have a note.
  • The first argument of the 'in' operator is a regular expression. Keep that in mind when deciding on what search you want to do.
  • Using the 'ans' variable isn't really necessary. You can instead use the return value of the 'if'. I use the variable to avoid problems if/when code is added after the if, just to be sure I am getting the return value I want.
  • IMPORTANT: While testing this I found a bug in the get_note() function. The 'plain_text' option doesn't work. I have submitted a fix to Kovid. I will post here when the fix is in calibre source. In the meantime use HTML instead of plain text (the third parameter to get_note() is ''). It will be significantly slower but it should work as long as what you are looking for doesn't resemble an HTML tag too closely.

Depending on what you want to do, there are two ways to proceed.
  1. You just want a column with a checkmark
    • Create a composite column using the above template, with "show checkmarks" True.
  2. You want a column icon
    • Create an advanced rule using the template, but return the image name instead of 'Yes' or 'No'
    or
    • Create a composite column using the above template Use this column in a column icon rule looking for the value 'Yes'. You might want to hide this column in the booklist and book details.
  3. You want both. Do the composite column in option 1 then use that column in the second choice for the column icon in option 2.

Last edited by chaley; Yesterday at 07:25 AM.
chaley is offline   Reply With Quote
Old Yesterday, 07:16 AM   #4
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,123
Karma: 6426808
Join Date: Sep 2020
Device: Calibre E-book viewer
Quote:
Originally Posted by chaley View Post
You can search a note using a template like this one, suitably modified.
Is it possible, currently, to run that on the Advanced Search template field?

I get "EXCEPTION: string indices must be integers, not 'str'" in the Template Editor.

I'm trying with: Comparison type - Text, and pasting the code in field Template, while leaving the field Template Value empty.
Comfy.n is offline   Reply With Quote
Old Yesterday, 07:24 AM   #5
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by Comfy.n View Post
Is it possible, currently, to run that on the Advanced Search template field?

I get "EXCEPTION: string indices must be integers, not 'str'" in the Template Editor.

I'm trying with: Comparison type - Text, and pasting the code in field Template, while leaving the field Template Value empty.
Yes, but the IMPORTANT part of my post is relevant. Until the fix is in calibre source you must use
Code:
get_note('authors', first_author, '')
chaley is offline   Reply With Quote
Old Yesterday, 07:54 AM   #6
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by chaley View Post
IMPORTANT: While testing this I found a bug in the get_note() function. The 'plain_text' option doesn't work. I have submitted a fix to Kovid. I will post here when the fix is in calibre source. In the meantime use HTML instead of plain text (the third parameter to get_note() is ''). It will be significantly slower but it should work as long as what you are looking for doesn't resemble an HTML tag too closely.
The fix is now in calibre source. If you run from source you can now use
Code:
get_note('authors', first_author, 1)
and not get the exception. If you don't run from source you must wait until the next calibre preview/release.
chaley is offline   Reply With Quote
Old Yesterday, 08:29 AM   #7
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,123
Karma: 6426808
Join Date: Sep 2020
Device: Calibre E-book viewer
Quote:
Originally Posted by chaley View Post
The fix is now in calibre source.
It works in the template editor, showing "Yes" for a given value when a book whose author's notes contain the string is currently selected.

However when I paste the template in the search bar, it returns no results, so I must be doing something the wrong way

Last edited by Comfy.n; Yesterday at 08:32 AM.
Comfy.n is offline   Reply With Quote
Old Yesterday, 08:42 AM   #8
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by Comfy.n View Post
It works in the template editor, showing "Yes" for a given value when a book whose author's notes contain the string is currently selected.

However when I paste the template in the search bar, it returns no results, so I must be doing something the wrong way
Works for me when using the advanced search template search builder running from latest source (with the fix). This example finds any note containing the letter 'a'.

Template:
Code:
program:
	first_author = sublist($authors, 0, 1, '&');
	note = get_note('authors', first_author, '1');
	if 'a' in note then
		ans = 'Yes'
	else
		ans = ''
	fi;
	ans
The template search dialog:
Click image for larger version

Name:	Clipboard01.jpg
Views:	18
Size:	67.6 KB
ID:	210791

Note that the template search generated by the dialog contains more than just the template.

Last edited by chaley; Yesterday at 08:44 AM.
chaley is offline   Reply With Quote
Old Yesterday, 09:45 AM   #9
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,123
Karma: 6426808
Join Date: Sep 2020
Device: Calibre E-book viewer
Quote:
Originally Posted by chaley View Post
Create a composite column using the above template, with "show checkmarks" True.
That works fine,

Click image for larger version

Name:	MWSnap 2024-09-12, 10_21_14.png
Views:	11
Size:	4.1 KB
ID:	210793

Now I'm trying to fix my advanced search issue, hopefully I can come up later with more detailed info. I think my notes database has grown too much lately, and when I do the search as indicated in your screenshot for Advanced Search, Calibre enters some seemingly infinite database lookup.

This has happened other times and I solved it by recreating my Bio column. (deleting it, then re-adding). Today this didn't seem to solve the issue. Process Monitor shows this:

Click image for larger version

Name:	MWSnap 2024-09-12, 10_43_46.png
Views:	24
Size:	104.4 KB
ID:	210792
Comfy.n is offline   Reply With Quote
Old Yesterday, 05:53 PM   #10
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by Comfy.n View Post
Now I'm trying to fix my advanced search issue, hopefully I can come up later with more detailed info. I think my notes database has grown too much lately, and when I do the search as indicated in your screenshot for Advanced Search, Calibre enters some seemingly infinite database lookup.
Your problem is almost certainly provoked by the size of your library. The template I posted above is not optimized for looking at >70,000 books, which is IIRC what you have in your library. It does a notes lookup for each book in the library. If that process takes 2 milliseconds per book then the search will run for 140 seconds. And who knows if 2ms is anywhere close to right.

This python template is optimized for the search problem. When it is first called (the first book) it gets all the note values and caches them using more optimized API calls. Then for each subsequent book it checks the cache, not the database. It would be best done as a stored template so the field and value could be passed as arguments. I didn't bother to do that because I don't know if this solves your problem.

The template:
Code:
python:
def evaluate(book, context):
	# Set these to what you want
	field_name = 'authors'
	search_value = 'aaa'

	db = context.db.new_api

	# check if we have already cached the notes
	note_items = context.globals.get('items_with_notes', None)
	if note_items is not None:
		# We have. Get the cached note values
		note_values = context.globals['note_values']
	else:
		# We haven't. Cache the note item ids and their values
		# First get all the item ids with notes and cache the result
		note_items = db.get_all_items_that_have_notes(field_name)
		context.globals['items_with_notes'] = note_items

		# Now get the note values for each item id with a note
		note_values = {}
		for note_item in note_items:
			note = db.notes_data_for(field_name, note_item)
			if note:
				# Get the plain text of the note
				note = note['searchable_text'].partition('\n')[2]
			# Put the value of the note into the cache.
			note_values[note_item] = note
		# Write the cached values to the globals
		context.globals['note_values'] = note_values

	# Check if this book is a match -- the field has a note containing the right text
	# get the item_id for the value of the desired field
	fv = book.get(field_name)
	# if the field is multi-valued, use the first value
	if isinstance(fv, list):
		fv = fv[0]
	# Now get the internal ID of the value in field_name
	item_id = db.get_item_id(field_name, fv)

	# Return the empty string if the item doesn't have a note
	if item_id not in note_items:
		return ''

	# Get the note value from the cache	
	val = note_values.get(item_id, None)
	if val is None: # This shouldn't happen, but ...
		return ''

	# use a case insensitive compare to check if the search value is in the note
	from calibre.utils.icu import primary_contains
	return 'Yes' if primary_contains(search_value, val) else ''
chaley is offline   Reply With Quote
Old Yesterday, 07:34 PM   #11
Comfy.n
want to learn what I want
Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.Comfy.n ought to be getting tired of karma fortunes by now.
 
Posts: 1,123
Karma: 6426808
Join Date: Sep 2020
Device: Calibre E-book viewer
Quote:
Originally Posted by chaley View Post
It would be best done as a stored template so the field and value could be passed as arguments. I didn't bother to do that because I don't know if this solves your problem.
Well, it took a while but it did complete the query, this time. I haven't timed it, but it finished much sooner than expected, considering my previous attempts.

Thanks for taking your time to try and help!

I had thought of asking for a stored template like "item_has_notes", but I think this is not the case at the moment.
Comfy.n is offline   Reply With Quote
Old Today, 06:40 AM   #12
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Moderator Notice
Moved to it's own thread
chaley is offline   Reply With Quote
Old Today, 06:45 AM   #13
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
I've thought of a way to significantly speed up the search template, calculating the text search result once per author instead of for every book. I'll post the new version later today.
chaley is offline   Reply With Quote
Old Today, 10:18 AM   #14
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,924
Karma: 7208979
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Here is the improved template. I'd be interested if you think it is faster.

Code:
python:
def evaluate(book, context):
    # Set these to what you want
    field_name = 'authors'
    value_in_note = 'a'

    db = context.db.new_api

    # check if we have already cached the notes
    note_items = context.globals.get('items_with_notes', None)
    if note_items is not None:
        # We've already fetched which items have notes.
        # Get the cached search result values
        note_search_results = context.globals['note_search_results']
    else:
        # First time. Get the items with notes and initialize
        # the search value cache.
        note_items = db.get_all_items_that_have_notes(field_name)
        context.globals['items_with_notes'] = note_items
        note_search_results = {}
        context.globals['note_search_results'] = note_search_results

    # Check if this book is a match -- that the field has a note containing
    # the desired text.
    
    # We must first get the item_id for the value in the field to be checked.
    field_value = book.get(field_name)
    # if the field is multi-valued, use the first value
    if isinstance(field_value, list):
        field_value = field_value[0]
    # Now get the internal ID of the value in field_name
    item_id = db.get_item_id(field_name, field_value)

    # Does the item have a note? If not, give up now.
    if item_id not in note_items:
        return ''

    # The item has a note. Have we already checked it?
    if item_id not in note_search_results:
        # Item has a note but we haven't seen it before. Do the compare
        # on the plain text version of the note.
        result = ''
        # Get the note.
        note = db.notes_data_for(field_name, item_id)
        if note:
            # Get the plain text of the note.
            note = note['searchable_text'].partition('\n')[2]
        if note:
            # use a case insensitive compare to check if the search value is in the note
            from calibre.utils.icu import primary_contains
            result = 'Yes' if primary_contains(value_in_note, note) else ''
        # Cache the result of the comparison
        note_search_results[item_id] = result
        context.globals['note_search_results'] = note_search_results
    # Return the cached value
    return note_search_results.get(item_id, '')
chaley is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Template Search: Exact matching ownedbycats Library Management 3 04-03-2022 05:01 PM
Template: Converting a search & replace into a template ownedbycats Library Management 11 03-26-2021 04:32 AM
Nova Pro : Notes Template MachinaCarnis Onyx Boox 0 01-30-2020 01:57 PM
template or search feature question bulldogmo Calibre 2 08-06-2014 06:34 PM


All times are GMT -4. The time now is 10:21 AM.


MobileRead.com is a privately owned, operated and funded community.