Giter Site home page Giter Site logo

freestrings / jsonpath Goto Github PK

View Code? Open in Web Editor NEW
120.0 8.0 37.0 2.88 MB

JsonPath engine written in Rust. Webassembly and Javascript support too

License: MIT License

Rust 85.73% Shell 1.66% HTML 1.97% JavaScript 10.11% Lua 0.52%
jsonpath webassembly json rustlang nodejs javascript parsing query

jsonpath's People

Contributors

ctron avatar dependabot[bot] avatar freestrings avatar gkorland avatar meirshpilraien avatar yoav-steinberg 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

jsonpath's Issues

Export required traits for parsing a json path

Hi, first of all thank you very much for this crate, helped me a lot.

I recently had to implement something where I had a bunch of partial json objects, each with its associated json path, and I had to build a json object from all those partial ones. In order to do this I had to parse each json path backwards in order to build my final json object. My code lies here.

But traits for doing this are not public. In the end, I would love to have those public use jsonpath_lib::{ParserNodeVisitor, ParserTokenHandler, ParseToken, StrRange};. I get that it is not the main purpose of the crate ; it is not aimed at being a parser.

I am willing to open a PR for that, I just wanted to have your consent (and explain why). WDYT ?

Thank you very much

Invalid result on second attribute check

Having a value of:

{
  "foo": {
    "first": { "second": "value" }
  },
  "foo2": {
    "first": {}
  },
  "foo3": {
  }
}

And a JSON path of:

$..[?(@.first && @.first.second)]

I would expect a result of:

[
	{
		"first": {
			"second": "value"
		}
	}
]

Which I get with other JSON Path implementations.

However, I do get:

[
  null
]

panic: index out of bounds in `SelectorMut::replace_with`

Hi,

I discovered the following panic while using SelectorMut::remove:

thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 2', /home/mohmann/.cargo/registry/src/github.com-1ecc6299db9ec823/jsonpath_lib-0.3.0/src/select/mod.rs:814:56
stack backtrace:
   0: rust_begin_unwind
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:101:14
   2: core::panicking::panic_bounds_check
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:77:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index_mut
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/slice/index.rs:190:14
   4: core::slice::index::<impl core::ops::index::IndexMut<I> for [T]>::index_mut
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/slice/index.rs:26:9
   5: <alloc::vec::Vec<T,A> as core::ops::index::IndexMut<I>>::index_mut
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/alloc/src/vec/mod.rs:2477:9
   6: jsonpath_lib::select::replace_value
             at /home/mohmann/.cargo/registry/src/github.com-1ecc6299db9ec823/jsonpath_lib-0.3.0/src/select/mod.rs:814:56
   7: jsonpath_lib::select::SelectorMut::replace_with
             at /home/mohmann/.cargo/registry/src/github.com-1ecc6299db9ec823/jsonpath_lib-0.3.0/src/select/mod.rs:958:17
   8: jsonpath_lib::select::SelectorMut::remove
             at /home/mohmann/.cargo/registry/src/github.com-1ecc6299db9ec823/jsonpath_lib-0.3.0/src/select/mod.rs:929:9
   9: jsonlib_crash::main
             at ./src/main.rs:8:19
  10: core::ops::function::FnOnce::call_once
             at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

The jsonpath_lib version is 0.3.0. Here is a minimal reproducer:

use jsonpath_lib::SelectorMut;
use serde_json::json;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let value = json!([1, 2, 3]);

    let mutated = SelectorMut::new()
        .str_path("$[*]")?
        .value(value)
        .remove()?
        .take();

    println!("{:?}", mutated);

    Ok(())
}

I expected mutated to contain an empty array, but got this panic instead. Please note that when using .delete() instead of .remove() this code does not panic but produces the expected result of an array which contains only nulls.

I suspect that the array length isn't recalculated correctly after removing elements.

Crash on replace_with

The following crashes:
Where current_data == {}

jsonpath_lib::replace_with(current_data, "$a", &mut |_v| {
})?;

Results do not match other implementations

The following queries provide results that do not match those of other implementations of JSONPath
(compare https://github.com/cburgmer/json-path-comparison/tree/master/comparison):

  • $[:]
    Input:
    ["first", "second"]
    
    Expected output:
    ["first", "second"]
    
    Error:
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "$[:]\n^^^^\n"', src/libcore/result.rs:997:5
    note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
    

For reference, the output was generated by the program in https://github.com/cburgmer/json-path-comparison/tree/master/implementations/Rust_jsonpath_lib.

Dot notation path containing a colon character fails to match

The following test fails due to the $.prod:id path

#[test]
fn colon_token_in_path() {
    setup();

    let payload = json!({
        "prod:id": "G637",
        "prod_name": "coffee table",
        "price": 194
    });

    select_and_then_compare("$.price", payload.clone(), json!([194]));

    select_and_then_compare("$.prod_name", payload.clone(), json!(["coffee table"]));

    select_and_then_compare("$.prod:id", payload.clone(), json!(["G637"]));
}

Returning an empty array []

test colon_token_in_path ... FAILED

failures:

---- colon_token_in_path stdout ----
thread 'colon_token_in_path' panicked at 'assertion failed: `(left == right)`
  left: `[]`,
 right: `[String("G637")]`: $.prod:id', tests/common.rs:41:5

Crash on jsonpath accesing null address

The following path "$.store.book[?(@.authors[0:].lastName)]" crash due to Accessing address: (nil)

Example JSON:

{
    "store": {
        "book": [
            {
                "authors": [
                    {
                        "firstName": "Nigel",
                        "lastName": "Rees"
                    },
                    {
                        "firstName": "Evelyn",
                        "lastName": "Waugh"
                    }
                ],
                "title": "Sayings of the Century"
            },
            {
                "authors": [
                    {
                        "firstName": "Herman",
                        "lastName": "Melville"
                    },
                    {
                        "firstName": "Somebody",
                        "lastName": "Else"
                    }
                ],
                "title": "Moby Dick"
            }
        ]
    }
}

Improve replace_with performance

Current replace_with code seems very inefficient

  1. Find all values.
  2. Compute all paths from values found in (1)
  3. Find values to replace again using paths from (2) to replace
        let paths = {
  (1)          let result = self.select()?;
  (2)         self.compute_paths(result)
        };

        if let Some(ref mut value) = &mut self.value {
            for tokens in paths {
  (3)              replace_value(tokens, value, fun);
            }
        }

It seems like the replace should account in step (1) while running select()

Invalid wildcard filter results

Awesome, thanks for the quick response.

I published an updated table.
There seems to be a regression that slipped in, see https://github.com/cburgmer/json-path-comparison/blob/master/comparison/results/wildcard_bracket_notation_on_array.md. If you are interested, I'm planning on compiling a consumable test set, possibly as a YAML artefact for library authors to consume and integrate (see https://github.com/cburgmer/json-path-comparison#roadmap).

Originally posted by @cburgmer in #6 (comment)

More flexible API

Hi, thank you for the library!

I am trying to use select with Vec<Rc<serde_json::Value>>, but it seems that the only option I have now is to construct a new array-like serde_json::Value. What about adding (or even replacing existing select methods) new pub trait for navigating in json or some other more flexible API? F.e. wolker that can in-depth and in-width move across json could suit here.

New release on crates.io?

Hello,

I'm working on a project that pulls in jsonpath_lib as a transitive dependency, and jsonpath's unexpected dependency on env_logger causes cargo-deny conflicts:

error[B004]: found 2 duplicate entries for crate 'env_logger'
   │  
30 │ ╭ env_logger 0.7.1 registry+https://github.com/rust-lang/crates.io-index
31 │ │ env_logger 0.8.3 registry+https://github.com/rust-lang/crates.io-index
   │ ╰──────────────────────────────────────────────────────────────────────^ lock entries
   │  

I see that this dependency has been removed in #66.

Are you planning to do a release sometime soon? I'd love to be able to be able to avoid the unnecessary dependency in my release code. Please let me know if there's anything I can do to make this easier :) Thanks!

Support Tilde

I would like to get the keys of the matching objects.
For example, when I have the following JSON:

{
   "a": {
       "check": true
   },
   "b": {
       "check": true
   },
   "c": {
       "check": false
   }
}

I want to get ["a","b"] with the following selector: $[?(@.check==true)]~

I know it's Jsonpath-Plus. But does this library support it? Is there any plan to go that way? Is there any way I achieve my goal with the current code?

why select always returns a vector? How to use this for single return value?

All examples for this library are around vectors. Not a single example shows how to fetch just a specific value from json using jsonpath. If select returns vector everytime, how would program know if returned value was actually an json array or json value?

Also there is incosistency in the results returned by select and select_as_str

I have below json. For json path $.args.foo1, select_as_str() returns "[\"bar1\"]" which is ofcourse wrong and select() doesn't return anything!! but empty array

{
    "args": {
        "foo1": "bar1",
        "foo2": "bar2"
    }
}

Allow gettting parse result when using `compile`

Currently the compile function returns impl FnMut(&Value) -> Result<Vec<&Value>, JsonPathError>. And the error of the parsing process is only evaluated when the function is called, typically when you select for data.

However, to me it would make sense to return ParseResult<impl FnMut(&Value) -> Result<Vec<&Value>, JsonPathError>> instead and simplify the actual implementation, dropping the "match" that is re-executed every time.

I would also do this myself, in a custom function. However the Parser is marked to be made private:

pub use parser::Parser; // TODO private

If that helps, I could create a PR to add new compile function which implements the suggested approach.

select returns value from array in json object instead of nothing

Consider:

    let j = json!({"f": [1,2,3]});
    let mut sel = Selector::new();
    let r = sel.str_path("$[0]").unwrap().value(&j).select().unwrap();
    for v in r {
        println!("{}", v);
    }

I'd expect nothing to be returned since the array is under the "f" field in the object and we're trying to reference the top level as if it's an array. Surprisingly the code prints 1 as if the array is in the top level.
This seems like a bug.

Failure to match "$..['$ref']", "$..['ref']", but succeeds on "$..ref"

Hi...
I'm trying to use the JsonPath with OpenAPI files...
there is a lot of redirect references that I can't extract of the form:

{
...
 "$ref": "#/x/y/z",
...
}

Given the following JSON

{
    "Junk1": "This is a test to illustrate use of '$' in the attr for the expression $..['$ref'] ",
    "$ref": "Match Root",
    "Subset1":[
        {"Junk2": "Data...",
         "$ref": "Match Subset1"
        }
    ],
    "hierachy1":{
        "hierachy2.1":{
            "hierachy2.1.1":{ "$ref":"Match 2.1.1"},
            "hierachy2.1.2":{ "ref":"Match 2.1.2"},
            "hierachy2.1.3":{ "ref":"No Match 2.1.3"},
            "hierachy2.1.4":{ "$ref":"Match 2.1.4"},
            "hierachy2.1.5":{ "ref":"No Match 2.1.5"}
        },
        "hierachy2.2":{
            "hierachy2.2.1":{ "ref":"No Match 2.2.1"},
            "hierachy2.2.2":{ "$ref":"Match 2.2.2"},
            "hierachy2.2.3":{ "ref":"No Match 2.2.3"},
            "hierachy2.2.4":{ "ref":"No Match 2.2.5"},
            "hierachy2.2.5":{ "$ref":"Match 2.2.5"}
        },
        "hierachy2.3":{
            "hierachy2.3.1":{ "ref":"No Match 2.3.1"},
            "hierachy2.3.2":{ "ref":"No Match 2.3.2"},
            "hierachy2.3.3":{ "ref":"No Match 2.3.3"},
            "hierachy2.3.4":{ "ref":"No Match 2.3.4"},
            "hierachy2.3.5":{ "ref":"No Match 2.3.5"},
            "hierachy2.3.6":{
                "hierachy2.3.6.1":{ "$ref":"Match 2.3.6.1"},
                "hierachy2.3.6.2":{ "ref":"No Match 2.3.6.2"},
                "hierachy2.3.6.3":{ "ref":"No Match 2.3.6.3"},
                "hierachy2.3.6.4":{ "ref":"No Match 2.3.6.4"},
                "hierachy2.3.6.5":{ "ref":"No Match 2.3.6.5"}
                }
            }
    }
}

Using the online JasonPath evaluator, The expressions "$..['$ref']", "$..[$ref]", "$..$ref" should yeild:
The

Select: [String("Match Root")
String("Match Subset1"),
String("Match 2.1.1"),
String("Match 2.1.4"),
String("Match 2.2.2"),
String("Match 2.2.5"),
String("Match 2.3.6.1")]

the expression "$..$ref" causes an error:
Select: Err(path error:
$..
^^^
)

This works: "$..ref"

Select: [String("Match 2.1.2"), String("No Match 2.1.3"), String("No Match 2.1.5"), String("No Match 2.2.1"), String("No Match 2.2.3"), String("No Match 2.2.5"), String("No Match 2.3.1"), String("No Match 2.3.2"), String("No Match 2.3.3"), String("No Match 2.3.4"), String("No Match 2.3.5"), String("No Match 2.3.6.2"), String("No Match 2.3.6.3"), String("No Match 2.3.6.4"), String("No Match 2.3.6.5")]

I'll be happy to contribute, if you have some indicator on where to look/fix
JR

Bracket notation after recursive descent does not recurse

Selector: $..[0]

Input:

["first", {"key": ["first nested", {"more": [{"nested": ["deepest", "second"]}, ["more", "values"]]}]}]

Expected output:

["deepest", "first nested", "first", "more", {"nested": ["deepest", "second"]}]

Actual output:

["first"]

Compare https://cburgmer.github.io/json-path-comparison/. For reference, the output was generated by the program in https://github.com/cburgmer/json-path-comparison/tree/master/implementations/Rust_jsonpath_lib.

Add support for the parent operator `^`

e.g.

$.store.book[*].authors[?(@.lastName=="Waugh")]^title

Example JSON:

{
    "store": {
        "book": [
            {
                "authors": [
                    {
                        "firstName": "Nigel",
                        "lastName": "Rees"
                    },
                    {
                        "firstName": "Evelyn",
                        "lastName": "Waugh"
                    }
                ],
                "title": "Sayings of the Century"
            },
            {
                "authors": [
                    {
                        "firstName": "Herman",
                        "lastName": "Melville"
                    },
                    {
                        "firstName": "Somebody",
                        "lastName": "Else"
                    }
                ],
                "title": "Moby Dick"
            }
        ]
    }
}

ref RedisJSON/RedisJSON#494

Select for Update/Delete

Is there a way to select for update/delete?

let result = selector
    .path("$..[?(@.age >= 30)]").unwrap()
    .value(&json_obj).delete() 

Modify code to use a generic underline json value

Today the code assumes the underline json structure is serde_json::Value. We have a situation where this is not the case and we need to work with a custom structure. We still want to use this library with our structure. I was wondering if you will accept a PR that changes the code to work with any value that implement a defined trait, this way it can be use with serde_json::Value but with other structures as well. If you agree we can use this issue to define the details and I will be happy to contribute the PR.

Util / TextDecoder is not a constructor

Hi guys,

might be the wrong place to ask, but I am testing this library since it might improve a lot of things on our end in terms of speed. Right now when I include the project, a browser reports "TextDecoder is not a constructor". I am new to WASM or WASM implementing packages, so I figured you guys might be able to help me out a bit.

I have a nodejs webpack setup that imports the package. Do you guys have any advice on how to approach this setup?

Filter with OR expression fails with non-existing value

Adding a test such as the following, fails when a filter contains an OR expression with one of its operands being compared to a none-existing value, e.g.,
Slightly modifying an existing test named op_object_or_default in op.rs:

#[test]
fn op_object_or_nonexisting_default() {
    setup();

    select_and_then_compare(
        "$.friends[?(@.id >= 2 || @.id == 4)]",
        read_json("./benchmark/data_obj.json"),
        json!([
            { "id" : 2, "name" : "Gray Berry" }
        ]),
    );
}

The selected result is empty, while it should be equal to the target json.

When removing the right operand || @.id == 4 it succeeds
(with filter "$.friends[?(@.id >= 2)]" )

Parser should throw an error on surplus text following the closing angle bracket of an array index

Path such as
$.store.book[0]category
Does not throw an error and is silently ignoring the surplus text category beyond the ]
And is parsed as $.store.book[0]

Can be demonstrated also on https://freestrings.github.io/jsonpath/
The same value is returned with and without the surplus text category.
Parser should throw an error on surplus text.

Notice that If there is a dot delimiter before the surplus text then everything is OK, e.g.,
$.store.book[0].category is working as expeced.

JSONPath comparison and standardisation

@cburgmer's JSONPath comparison project is currently discussing some issues relating to a proposed implementation of JSONPath known as "Proposal A". May I encourage you to get involved if you are interested in influencing the direction or, indeed, if you want to make your own proposals.

Similarly, please join us in slack (invitation) for informal discussions on the comparison project and potential JSONPath standardisation.

Nested filter are ignored

The following path "$.store.book[?(@.authors[?(@.lastName1)])]" returns both books despite the fact none has lastName1 attribute.

Example JSON:

{
    "store": {
        "book": [
            {
                "authors": [
                    {
                        "firstName": "Nigel",
                        "lastName": "Rees"
                    },
                    {
                        "firstName": "Evelyn",
                        "lastName": "Waugh"
                    }
                ],
                "title": "Sayings of the Century"
            },
            {
                "authors": [
                    {
                        "firstName": "Herman",
                        "lastName": "Melville"
                    },
                    {
                        "firstName": "Somebody",
                        "lastName": "Else"
                    }
                ],
                "title": "Moby Dick"
            }
        ]
    }
}

ref RedisJSON/RedisJSON#494

Crash on jsonpath_lib::select

JSON: {"fi":[{"code":"1"}, {"code":"2"}]}

JSONPath: "$.fi[?(@.code==\"2\")]"

_mm_load_si128 (@core::core_arch::x86::sse2::_mm_load_si128::h31ad0ac98cca243e:7)
load_aligned (@hashbrown::raw::sse2::Group::load_aligned::h07726ae12d146f0a:13)
new<(*const serde_json::value::Value, ())> (@hashbrown::raw::RawIterRange$LT$T$GT$::new::h315ac80c6dd69c8c:18)
iter<(*const serde_json::value::Value, ())> (@hashbrown::raw::RawTable$LT$T$GT$::iter::he64f03d3a2e7376b:32)
resize<(*const serde_json::value::Value, ()),closure-1> (@hashbrown::raw::RawTable$LT$T$GT$::resize::h150c3f3ba9377904:125)
reserve_rehash<(*const serde_json::value::Value, ()),closure-1> (@hashbrown::raw::RawTable$LT$T$GT$::reserve_rehash::h57be3f64f169106b:111)
reserve<(*const serde_json::value::Value, ()),closure-1> (@hashbrown::raw::RawTable$LT$T$GT$::reserve::h49982cfae6135115:23)
insert<(*const serde_json::value::Value, ()),closure-1> (@hashbrown::raw::RawTable$LT$T$GT$::insert::h1fd330f9eb644a76:69)
insert<*const serde_json::value::Value,(),std::collections::hash::map::RandomState> (@hashbrown::map::HashMap$LT$K$C$V$C$S$GT$::insert::h389f0db0a85a5c9d:62)
insert<*const serde_json::value::Value,(),std::collections::hash::map::RandomState> (@std::collections::hash::map::HashMap$LT$K$C$V$C$S$GT$::insert::hc8ac2a757d3d118a:10)
insert<*const serde_json::value::Value,std::collections::hash::map::RandomState> (@std::collections::hash::set::HashSet$LT$T$C$S$GT$::insert::h39fb5ee15d35a1ef:10)
_collect (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:629)
_collect (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:636)
{{closure}} (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:646)
in_filter<closure-0> (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:600)
next_in_filter_with_str (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:643)
visit_key (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:862)
visit_token (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:1008)
visit<jsonpath_lib::select::Selector> (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/parser/mod.rs:631)
visit<jsonpath_lib::select::Selector> (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/parser/mod.rs:641)
visit<jsonpath_lib::select::Selector> (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/parser/mod.rs:670)
visit<jsonpath_lib::select::Selector> (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/parser/mod.rs:652)
_select (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:531)
select (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/select/mod.rs:567)
select (/home/guy/.cargo/git/checkouts/jsonpath-dd869ee3d7fc4db5/9918581/src/lib.rs:303)
get_values (/home/guy/redislabsmodules/RedisDoc/src/redisjson.rs:374)
get_first (/home/guy/redislabsmodules/RedisDoc/src/redisjson.rs:366)
to_string (/home/guy/redislabsmodules/RedisDoc/src/redisjson.rs:186)
json_get (/home/guy/redislabsmodules/RedisDoc/src/lib.rs:209)
{{closure}} (@redisjson::RedisModule_OnLoad::do_command::_$u7b$$u7b$closure$u7d$$u7d$::h0659299eccc9dc42:16)
map<alloc::vec::Vec<alloc::string::String>,redis_module::rediserror::RedisError,core::result::Result<redis_module::redisvalue::RedisValue, redis_module::rediserror::RedisError>,closure-1> (@core::result::Result$LT$T$C$E$GT$::map::h3a0cae1cd1f1a3d3:43)
do_command (@redisjson::RedisModule_OnLoad::do_command::h01c2678cb31556a8:43)
RedisModuleCommandDispatcher (/home/guy/workspace/redis/src/module.c:543)
call (/home/guy/workspace/redis/src/server.c:2439)
processCommand (/home/guy/workspace/redis/src/server.c:2733)
processInputBuffer (/home/guy/workspace/redis/src/networking.c:1470)
aeProcessEvents (/home/guy/workspace/redis/src/ae.c:443)
aeMain (/home/guy/workspace/redis/src/ae.c:501)
main (/home/guy/workspace/redis/src/server.c:4200)

Duplicate results no filter

Filter might return duplicate results when the internal objects are similar.

e.g. input JSON both objects have name == {"first":"A","middle":"A"}

[{{"name":{"first":"A","middle":"A"},"rank":8},{"name":{"first":"A","middle":"A"},"rank":90}]

When running:

$[?($.name.first=="A")]

The following result is returned:

[{{"name":{"first":"A","middle":"A"},"rank":8},{"name":{"first":"A","middle":"A"},"rank":8},{{"name":{"first":"A","middle":"A"},"rank":90},{"name":{"first":"A","middle":"A"},"rank":90}]

It seems like the bug is in this code which compares all the candidates with all values and return each "parent" twice.

for result_value in &ret {

ref RedisJSON/RedisJSON#667

replace_with call back function should be able to return an Error

The current callback defined:

FnMut(&Value) -> Value

Allowing the callback to return a Result will allow the callback "abort" replace in case it can't be done.

FnMut(&Value) -> Result<Value, JsonPathError>

Perhaps a new method should be added

pub fn try_replace_with<F>(value: Value, path: &str, fun: &mut F) -> Result<Value, JsonPathError>
where
    F: FnMut(&Value) -> Result<Value, JsonPathError>,

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.