mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-03 20:07:09 +02:00
feat: Introduce a WordArea struct
Useful to highlight matching areas in the original text.
This commit is contained in:
parent
62521262e8
commit
b32c96cdc9
14 changed files with 373 additions and 136 deletions
|
@ -2,10 +2,12 @@ use std::io::{self, Write};
|
|||
use std::path::PathBuf;
|
||||
use std::error::Error;
|
||||
|
||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use structopt::StructOpt;
|
||||
|
||||
use meilidb::database::Database;
|
||||
use meilidb::Match;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct Opt {
|
||||
|
@ -26,6 +28,40 @@ struct Document {
|
|||
image: String,
|
||||
}
|
||||
|
||||
fn display_highlights(text: &str, ranges: &[usize]) -> io::Result<()> {
|
||||
let mut stdout = StandardStream::stdout(ColorChoice::Always);
|
||||
let mut highlighted = false;
|
||||
|
||||
for range in ranges.windows(2) {
|
||||
let [start, end] = match range { [start, end] => [*start, *end], _ => unreachable!() };
|
||||
if highlighted {
|
||||
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
|
||||
}
|
||||
write!(&mut stdout, "{}", &text[start..end])?;
|
||||
stdout.reset()?;
|
||||
highlighted = !highlighted;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_highlight_areas(text: &str, matches: &[Match], attribute: u16) -> Vec<usize> {
|
||||
let mut title_areas = Vec::new();
|
||||
|
||||
title_areas.push(0);
|
||||
for match_ in matches {
|
||||
if match_.attribute.attribute() == attribute {
|
||||
let word_area = match_.word_area;
|
||||
let byte_index = word_area.byte_index() as usize;
|
||||
let length = word_area.length() as usize;
|
||||
title_areas.push(byte_index);
|
||||
title_areas.push(byte_index + length);
|
||||
}
|
||||
}
|
||||
title_areas.push(text.len());
|
||||
title_areas
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<Error>> {
|
||||
let opt = Opt::from_args();
|
||||
|
||||
|
@ -41,26 +77,35 @@ fn main() -> Result<(), Box<Error>> {
|
|||
io::stdout().flush()?;
|
||||
|
||||
if input.read_line(&mut buffer)? == 0 { break }
|
||||
let query = buffer.trim_end_matches('\n');
|
||||
|
||||
let view = database.view();
|
||||
|
||||
let (elapsed, documents) = elapsed::measure_time(|| {
|
||||
let builder = view.query_builder().unwrap();
|
||||
builder.query(&buffer, 0..opt.number_results)
|
||||
builder.query(query, 0..opt.number_results)
|
||||
});
|
||||
|
||||
let mut full_documents = Vec::with_capacity(documents.len());
|
||||
let number_of_documents = documents.len();
|
||||
for doc in documents {
|
||||
match view.retrieve_document::<Document>(doc.id) {
|
||||
Ok(document) => {
|
||||
|
||||
for document in documents {
|
||||
match view.retrieve_document::<Document>(document.id) {
|
||||
Ok(document) => full_documents.push(document),
|
||||
print!("title: ");
|
||||
let title_areas = create_highlight_areas(&document.title, &doc.matches, 1);
|
||||
display_highlights(&document.title, &title_areas)?;
|
||||
println!();
|
||||
|
||||
print!("description: ");
|
||||
let description_areas = create_highlight_areas(&document.description, &doc.matches, 2);
|
||||
display_highlights(&document.description, &description_areas)?;
|
||||
println!();
|
||||
},
|
||||
Err(e) => eprintln!("{}", e),
|
||||
}
|
||||
}
|
||||
|
||||
println!("{:#?}", full_documents);
|
||||
println!("Found {} results in {}", full_documents.len(), elapsed);
|
||||
|
||||
println!("Found {} results in {}", number_of_documents, elapsed);
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue