adriank / ObjectPath

The agile query language for semi-structured data
http://objectpath.org
MIT License
380 stars 93 forks source link

Return more than one elements in the final list #59

Closed ghost closed 6 years ago

ghost commented 6 years ago

I am using the books (json) that you are using in the tutorial and I would like to retrieve the result of the following query:

$..[@.author is 'Evelyn Waugh' and @.title is 'Sword of Honour'] and $..[@.author is 'Nigel Rees' and @.title is 'Sayings of the Century']

this returns only 1 object: [{ "category": "reference", "price": 8.95, "title": "Sayings of the Century", "author": "Nigel Rees" }]

I would expect to get two entities back, one for Sword of Honour and one for Sayings of the Century. Is this feasible?

adriank commented 6 years ago

Hi,

I wonder if it's not a bug (it should return true probably), but generally, if you want to merge results from two expressions, use + instead of and between $..[...'Evelyn and $..[...'Nigel.

Greetings, Adrian Kalbarczyk

http://kalbarczyk.co

On Tue, Jan 9, 2018 at 9:19 AM, std::lef notifications@github.com wrote:

I am using the books (json) that you are using in the tutorial and I would like to retrieve the result of the following query:

$..[@.author is 'Evelyn Waugh' and @.title is 'Sword of Honour'] and $..[@.author is 'Nigel Rees' and @.title is 'Sayings of the Century']

this returns only 1 object: [{ "category": "reference", "price": 8.95, "title": "Sayings of the Century", "author": "Nigel Rees" }]

I would expect to get two entities back, one for Sword of Honour and one for Sayings of the Century. Is this feasible?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/adriank/ObjectPath/issues/59, or mute the thread https://github.com/notifications/unsubscribe-auth/AAKycq6W5_a3bX3sfWZwUGzmKzj-iRUDks5tIyEugaJpZM4RXdob .

ghost commented 6 years ago

Hello Adrian,

Thanks for your prompt reply. I believe there is a bug in the code. Here is an example


[
  {
    "a": 10,
    "b": 11
  },
  {
    "a": 20,
    "b": 21
  }
]

 $..*[@.a is 10 and @.b is 11]
[{
  "a": 10,
  "b": 11
}]
 $..*[@.a is 10 and @.b is 11] and  $..*[@.a is 20 and @.b is 21]
[{
  "a": 20,
  "b": 21
}]
$..*[@.a is 20 and @.b is 11] and  $..*[@.a is 20 and @.b is 21]
[{
  "a": 20,
  "b": 21
}]

**$..*[@.a is 10 and @.b is 11]** returns the first element, however 
**$..*[@.a is 20 and @.b is 11] and  $..*[@.a is 20 and @.b is 21]** returns only the second. As you said above I would expect to return true since the first expression had list.size>0 and the second subexpression also. 

If you take a look closely at the third expression **$..*[@.a is 20 and @.b is 11] and  $..*[@.a is 20 and @.b is 21]** returns the second object, however the first element should not even match (a is 10 in the JSON and not 20). 

Any chance to "offer' this functionality?

Thanks,
Lef
adriank commented 6 years ago

Hi,

I'm not coding in Python since 2013, so there is little chance that I would be able to fix it in foreseeable future. You can try with len():

len($..[@.a is 20 and @.b is 11]) and len($..[@.a is 20 and @.b is 21])

Greetings, Adrian Kalbarczyk

http://kalbarczyk.co

On Tue, Jan 9, 2018 at 11:21 AM, std::lef notifications@github.com wrote:

Hello Adrian,

Thanks for your prompt reply. I believe there is a bug in the code. Here is an example

[ { "a": 10, "b": 11 }, { "a": 20, "b": 21 } ]

$..[@.a is 10 and @.b is 11] [{ "a": 10, "b": 11 }] $..[@.a is 10 and @.b is 11] and $..[@.a is 20 and @.b is 21] [{ "a": 20, "b": 21 }] $..[@.a is 20 and @.b is 11] and $..*[@.a is 20 and @.b is 21] [{ "a": 20, "b": 21 }]

*$..[@.a is 10 and @.b is 11] returns the first element, however $..[@.a is 20 and @.b is 11] and $..[@.a is 20 and @.b is 21]** returns only the second. As you said above I would expect to return true since the first expression had list.size>0 and the second subexpression also.

If you take a look closely at the third expression $..[@.a is 20 and @.b is 11] and $..[@.a is 20 and @.b is 21] returns the second object, however the first element should not even match (a is 10 in the JSON and not 20).

Any chance to "offer' this functionality?

Thanks, std::lef

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/adriank/ObjectPath/issues/59#issuecomment-356242318, or mute the thread https://github.com/notifications/unsubscribe-auth/AAKycsNSyoiJrNWClmXLeTd816dQ_0Wtks5tIz2cgaJpZM4RXdob .

ghost commented 6 years ago

Thanks it worked.

adriank commented 5 years ago

OK, I have a project where I'm using the ObjectPath myself and I know a little bit more now.

The is operator is taken directly from Python and behaves in the exact same way. Refer to Python documentation to see how it works.

>>> 3 and 4 => 4

So that's why your query returns the last object.

Should it work like that in ObjectPath? I need to think about that.