Skip to content

Commit

Permalink
Implement script fields
Browse files Browse the repository at this point in the history
  • Loading branch information
buinauskas committed Jun 29, 2023
1 parent d875f59 commit c949319
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod queries;
pub mod request;
pub mod rescoring;
pub mod runtime_mappings;
pub mod script_fields;
pub mod sort;
pub mod suggesters;

Expand All @@ -33,5 +34,6 @@ pub use self::request::*;
pub use self::rescoring::*;
pub use self::response::*;
pub use self::runtime_mappings::*;
pub use self::script_fields::*;
pub use self::sort::*;
pub use self::suggesters::*;
Empty file.
13 changes: 13 additions & 0 deletions src/search/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub struct Search {
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
docvalue_fields: Set<String>,

#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
script_fields: Map<String, ScriptField>,

#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
post_filter: Option<Query>,
}
Expand All @@ -76,6 +79,16 @@ impl Search {
self
}

/// Add script fields to the search request
pub fn script_fields<S, T>(mut self, name: S, script: T) -> Self
where
S: ToString,
T: Into<ScriptField>,
{
let _ = self.script_fields.insert(name.to_string(), script.into());
self
}

/// Allows to configure different boost level per index when searching
/// across more than one indices. This is very handy when hits coming from
/// one index matter more than hits coming from another index (think social
Expand Down
85 changes: 85 additions & 0 deletions src/search/script_fields/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//! You can use the `script_fields` parameter to retrieve a
//! [script evaluation](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html)
//! (based on different fields) for each hit.
//!
//! <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#script-fields>

use crate::Script;

/// A script to calculate field value from the `_source` fields
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ScriptField {
script: Script,
}

impl From<Script> for ScriptField {
fn from(value: Script) -> Self {
Self { script: value }
}
}

impl From<&str> for ScriptField {
fn from(value: &str) -> Self {
Self {
script: Script::source(value),
}
}
}

impl From<String> for ScriptField {
fn from(value: String) -> Self {
Self {
script: Script::source(value),
}
}
}

#[cfg(test)]
mod tests {
use crate::{util::assert_serialize, Search};

use super::*;

#[test]
fn serializes_correctly() {
let subject = Search::new()
.script_fields(
"test1",
Script::source("doc['price'].value * 2").lang("painless"),
)
.script_fields(
"test2",
Script::source("doc['price'].value * params.factor")
.lang("painless")
.param("factor", 2.0),
)
.script_fields("test3", "params['_source']['message']");

let expectation = json!({
"script_fields": {
"test1": {
"script": {
"lang": "painless",
"source": "doc['price'].value * 2"
}
},
"test2": {
"script": {
"lang": "painless",
"source": "doc['price'].value * params.factor",
"params": {
"factor": 2.0
}
}
},
"test3": {
"script": {
"source": "params['_source']['message']"
}
}
}
});

assert_serialize(subject, expectation);
}
}

0 comments on commit c949319

Please sign in to comment.