Giter VIP home page Giter VIP logo

elasticsearch-dsl-rs's Introduction

Strongly typed Elasticsearch DSL written in Rust

Crates.io Crates.io Crates.io Docs.io Rust

A high level library, giving a strongly typed DSL that maps one to one with the official Elasticsearch query DSL.

Features

  • Strongly typed queries
  • Strongly typed aggregations
  • Strongly typed completions
  • Response structures
  • Automatically skips empty queries making DSL pleasant to use
  • Crate doesn't depend on elasticsearch-rs and can be used as a standalone library with any HTTP client to call Elasticsearch

Installation

Add elasticsearch-dsl crate and version to Cargo.toml

[dependencies]
elasticsearch-dsl = "0.4"

Documentation

Documentation for the library is available on docs.rs

Quick start

use elasticsearch_dsl::*;

fn main() {
    let query = Search::new()
        .source(false)
        .stats("statistics")
        .from(0)
        .size(30)
        .query(
            Query::bool()
                .must(Query::multi_match(
                    ["title", "description"],
                    "you know, for search",
                ))
                .filter(Query::terms("tags", ["elasticsearch"]))
                .should(Query::term("verified", true).boost(10)),
        )
        .aggregate(
            "country_ids",
            Aggregation::terms("country_id")
                .aggregate("catalog_ids", Aggregation::terms("catalog_id"))
                .aggregate("company_ids", Aggregation::terms("company_id"))
                .aggregate(
                    "top1",
                    Aggregation::top_hits()
                        .size(1)
                        .sort(FieldSort::ascending("user_id")),
                ),
        )
        .rescore(Rescore::new(Query::term("field", 1)).query_weight(1.2));
}
{
  "_source": false,
  "stats": ["statistics"],
  "from": 0,
  "size": 30,
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "fields": ["title", "description"],
            "query": "you know, for search"
          }
        }
      ],
      "filter": [{ "terms": { "tags": ["elasticsearch"] } }],
      "should": [{ "term": { "verified": { "value": true, "boost": 10.0 } } }]
    }
  },
  "aggs": {
    "country_ids": {
      "terms": { "field": "country_id" },
      "aggs": {
        "catalog_ids": { "terms": { "field": "catalog_id" } },
        "company_ids": { "terms": { "field": "company_id" } },
        "top1": {
          "top_hits": {
            "size": 1,
            "sort": [{ "user_id": { "order": "asc" } }]
          }
        }
      }
    }
  },
  "rescore": [
    {
      "query": {
        "rescore_query": { "term": { "field": { "value": 1 } } },
        "query_weight": 1.2
      }
    }
  ]
}

See examples for more.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

elasticsearch-dsl-rs's People

Contributors

alpoi-x avatar buinauskas avatar dainiusjocas avatar dmitrysamoylov avatar frederickfrance avatar fulmicoton avatar github-actions[bot] avatar iamazy avatar jakimcikas avatar jbcrail avatar jonasbakys0 avatar mykolas-kairys avatar oknozor avatar oleg-vinted avatar yaymukund avatar ypenglyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elasticsearch-dsl-rs's Issues

Why not "_mut" for many functions ?

Hi

Sometimes, it isn't necessary to takes ownership of the receiver self.

I propose something like:


impl BoolQuery {
    /// The clause (query) must appear in matching documents and will contribute to the score.
    pub fn must<T>(mut self, query: T) -> Self
    where
        T: IntoIterator,
        T::Item: Into<Query>,
    {
        self.must.extend(query);
        self
    }

    /// The clause (query) must appear in matching documents and will contribute to the score.
    pub fn must_mut<T>(&mut self, query: T)
    where
        T: IntoIterator,
        T::Item: Into<Query>,
    {
        self.must.extend(query);
    }

    /// The clause (query) should appear in the matching document.
    pub fn should<T>(mut self, query: T) -> Self
    where
        T: IntoIterator,
        T::Item: Into<Query>,
    {
        self.should.extend(query);
        self
    }

    /// The clause (query) must appear in matching documents.
    /// However unlike must the score of the query will be ignored.
    /// Filter clauses are executed in [filter context](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html),
    /// meaning that scoring is ignored and clauses are considered for caching.
    pub fn filter<T>(mut self, query: T) -> Self
    where
        T: IntoIterator,
        T::Item: Into<Query>,
    {
        self.filter.extend(query);
        self
    }

    /// The clause (query) must not appear in the matching documents.
    /// Clauses are executed in [filter context](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html)
    /// meaning that scoring is ignored and clauses are considered for caching.
    /// Because scoring is ignored, a score of `0` for all documents is returned.
    pub fn must_not<T>(mut self, query: T) -> Self
    where
        T: IntoIterator,
        T::Item: Into<Query>,
    {
        self.must_not.extend(query);
        self
    }

    /// You can use the `minimum_should_match` parameter to specify the number
    /// or percentage of should clauses returned documents must match.
    ///
    /// If the `bool` query includes at least one `should` clause and no
    /// `must` or `filter` clauses, the default value is `1`.
    /// Otherwise, the default value is `0`.
    ///
    /// For other valid values, see the
    /// [minimum_should_match parameter](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-minimum-should-match.html).
    pub fn minimum_should_match<T>(mut self, minimum_should_match: T) -> Self
    where
        T: ToString,
    {
        self.minimum_should_match = Some(minimum_should_match.to_string());
        self
    }

    add_boost_and_name!();
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_mut_must() {
        let mut test = Query::bool();
        test.must_mut(Query::term("abc", "def"));

        assert_eq!(Query::bool().must(Query::term("abc", "def")),test);
    }
}

Another good improvement could be to do some changes to be able to have something like that:

impl QueryCollection {
    fn dedup(&self) {
        self.0.sort_unstable();
        self.0.dedup()
    }
}

And maybe a way to simplify or validate some requests (find tautology if QueryCollection has 2 exact same elements, find contradiction if an element in must has an exact copy in must_not, find "law of excluded middle" if we find in should "must:A" and "must_not:A", ...).

I don't propose a merge request about at least the first improvement ( (must|shoudl|must_not)_mut) for the moment, I prefer to ask some opinions.

Specifying Index in search query

Hiya!

Library looks fantastic!

Was just wondering if there's some way to limit a query to a specific index?
Similar to how the elastic-search rs library accepts an index-id:

es_client.search(SearchParts::Index(&[&index_id]))
               .from(0)
               // etc etc

Query builder return empty query instead of failing

The following query get serialized to an empty string, I guess the function_score is skipped during
serialization.

    let query = Query::bool().should(
        Query::function_score()
            .boost_mode(FunctionBoostMode::Replace)
            .function(
                Function::decay(
                    DecayFunction::Gauss,
                    "coord",
                    GeoLocation::new(0.0, 0.0),
                    Distance::Meters(5000),
                )
                .offset(Distance::Meters(1000))
                .weight(0.5)
                .decay(0.3),
            ),
    );

the output json:

{
  "bool": {}
}

Point in time

Hi,

I'm trying to use PIT but I don't find how to do.

My code is similar as :

let client = Elasticsearch::default();
let s = client.search(SearchParts::None).size(1000).timeout("120s");
let search = Search::new().query(my_bool_query);
let response = s.body(json!(search)).allow_no_indices(true).send().await?;

What I understand :

  • if I want to use a scroll, I can write let s = client.search(SearchParts::None).scroll("100s").size(1000).timeout("120s"); (and close it later)
  • if I want to open or close a point in time, I can open and close one.

I don't understand how to add the pit id in the search.

Point in Time

Hi

I would like to use search_after with a point in time.

From what I understand, I should open a PIT with elasticsearch_rs, create a search with elasticsearch_dsl::search::request::Search::new().query(my_query).pit(my_pit).sort(["_id"]), continue with elasticsearch_dsl::search::request::Search::new().query(my_query).pit(my_pit).search_after(previous_sort_values) until getting all asked data, and finally close the PIT.

But I don't find a way to add the pit in my search.

Could you add it, please ?

Comment //TODO

Hi,

I see

impl SpanNearQuery {
    /// TODO
    pub fn in_order(mut self, in_order: bool) -> Self {
        self.in_order = Some(in_order);
        self
    }

    /// TODO
    pub fn slop(mut self, slop: i32) -> Self {
        self.slop = Some(slop);
        self
    }
}

How does the TODO mean ? "TODO a comment for the function" ?

Thanks for this crate but I think that it is sorely lacking in comments.

Function score with filter terms and weight

Hello, I am trying to write the following query:

    json!({
        "function_score": {
            "boost_mode": "replace",
            "functions": [
                {
                    "filter": { "term": { "type": "stop" } },
                    "field_value_factor": {
                        "field": "weight",
                        "factor": build_weight.factor,
                        "missing": build_weight.missing
                    },
                    "weight": types.stop
                },
                {
                    "filter": { "term": { "type": "address" } },
                    "filter": { "term": { "type": "addr" } },
                    "field_value_factor": {
                        "field": "weight",
                        "factor": build_weight.factor,
                        "missing": build_weight.missing
                    },
                    "weight": types.address
                },
                {
                    "filter": { "term": { "type": "admin" } },
                    "field_value_factor": {
                        "field": "weight",
                        "factor": build_weight.factor,
                        "missing": build_weight.missing
                    },
                    "weight": types.admin
                },
                {
                    "filter": { "term": { "type": "poi" } },
                    "field_value_factor": {
                        "field": "weight",
                        "factor": build_weight.factor,
                        "missing": build_weight.missing
                    },
                    "weight": types.poi
                },
                {
                    "filter": { "term": { "type": "street" } },
                    "field_value_factor": {
                        "field": "weight",
                        "factor": build_weight.factor,
                        "missing": build_weight.missing
                    },
                    "weight": types.street
                }
            ]
        }
    })

According to the elastic search dsl documentation function could be combined (see: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html).

Also I think the function score inner Query should be optional.

This does not seems to be possible at the moment. Or I am missing something ?

Remove unstable key-value attributes

elasticsearch_dsl does not compile on stable Rust, which is a blocker for my company's use of this crate. It looks like the only unstable feature is this one, and it would only change one line of code: #![doc = include_str!("../README.md")]. Thoughts on removing this?

Aggregation is complex

Hi

Aggregations are very blurred in my mind.

I'm trying to do :

 "aggs": {
    "timeline": {
      "date_histogram": {
        "field": "audit_date",
        "calendar_interval": "month",
        "min_doc_count": 1,
        "time_zone": "+02:00"
      }
    }
  }

But I don't understand how to do ๐Ÿ˜ข

Regards

Add Deserialize

The QueryDSL makes it possible to serialize the query. Would it be ok to add the Deserialize implementation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.