Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Requirement

we would like to bring support for contains operator in cps-path. 

contains() is a method in XPath expression. It is used when the value of any attribute changes dynamically, below are the examples,

Reference

CPS-1272

Issues & decisions

Native query for Contains Operator  using Like Keyword :

#

Issue

Notes 

Notes

Decision
Decisions
1Which keyword to use ? Do we want case sensitivity or not? Do we follow the Xpath contains or do we become specific?
  • like %en% 
  • ilike %En% 
  • like 'en' 


  As per discussion , with Toine Siebelink  , community call  like keyword would has consistency which support case sensitive attribute values.

Need to discuss with stakeholders.

  As per discussion in community call , decided to go with like  keyword more consistent support case sensitivity.


#

Json Data

CPS-PATH Syntax

Output

1

Below is the sample data ,
 Here  are ways  to use contains keyword :
Code Block
titleJson data
collapsetrue
{
  

In this example, we can identify the element by using leaf-name and leaf-value. In this cps-path expression leaf-name=lang and leaf-value=english.

sample json data :

{
 
 "test:bookstore":{


      "bookstore-name": "Chapters",


      "categories": [


         {


            "code": "01",


            "name": "SciFi",


            "books": [


               {


                  "authors": [


                     "Iain M. Banks"


                  ],


                  "lang": "english",


                  "price": "895",


                  "pub_year": "1994",


                  "title": "Feersum Endjinn"


               }


            ]


         },


         {


            "name": "kids",


            "code": "02",


            "books": [


               {


                  "authors": [


                     "Philip Pullman"


                  ],


                  "lang": "Science",


                  "price": "699",


                  "pub_year": "1995",


                  "title": "The Golden Compass"


               }


            ]


         }


   
 
 ]


   }


}
Syntax:


<cps-path>(contains'[@leafname,'<string-value>']')

Examples
  • //books[contains(@lang,'
english
  • en')
  • //books[contains(@pub_year,'99')
2

In this example, we can identify the element by  using partial  value of the attribute. In this cps-path expression partial value ‘en’ is used in place of english and science

sample json data :

{
   "test:bookstore":{
      "bookstore-name": "Chapters",
      "categories": [
         {
            "code": "01",
            "name": "SciFi",
            "books": [
               {
                  "authors": [
                     "Iain M. Banks"
                  ],
                  "lang": "english",
                  "price": "895",
                  "pub_year": "1994",
                  "title": "Feersum Endjinn"
               }
            ]
         },
         {
            "name": "kids",
            "code": "02",
            "books": [


Code Block
titleJson Response
collapsetrue
{
 "lang": "en", 
 "price": 895, 
 "title": "Feersum Endjinn", 
 "authors": [
            "Iain M. Banks"
 ], 
"pub_year":1994
}  
{
 "lang": "en", 
 "price": 699, 
 "title": "The Golden Compass", 
 "authors": [
           "Philip Pullman"
 ], 
"pub_year":1995
}            

                           

{

                 

"authors": [

                     

"Philip Pullman"

                 

],

           

      "lang": "Science",

  
                 

"price": "699",

                 

"pub_year": "1995",

                 

"title": "The Golden Compass"

           

   }

           

]

         

}
      ]
   }
}

Syntax: <cps-path> ( contains '[@leafname,'<string-partial value> ']' )

 Examples

  • //books[contains(@pub_year,'99')]

Here , it  search the books that contains  '99' as sub string value in attribute pub_year.

3

In this example, we can identify the element by using text() element and its value. In this cps-path expression leaf-name=title and leaf-value=The Golden Compass.

sample json data :

{
   "test:bookstore":{
      "bookstore-name": "Chapters",
      "categories": [
         {
            "code": "01",
            "name": "SciFi",
            "books": [
               {
                  "authors": [
                     "Iain M. Banks"
                  ],
                  "lang": "english",
                  "price": "895",
                  "pub_year": "1994",
                  "title": "Feersum Endjinn"
               }
            ]
         },
         {
            "name": "kids",
            "code": "02",
            "books": [
               {
                  "authors": [
                     "Philip Pullman"
                  ],
                  "lang": "Science",
                  "price": "699",
                  "pub_year": "1995",
                  "title": "The Golden Compass"
               }
            ]
         }
      ]

Syntax: <cps-path> (  contains '[@text(),' <string-value> ']' )

Examples

  • //books/title[contains(@text(),'The Golden')]

 Query format for contains keyword 


Native Query for contains keyword

1.Using LIKE Keyword :

Like operator is used to match specified matching pattern. It has two signs :

% : Matches any sequence of character, the character size may be 0 or more.

_ : Matches any single character.

#

Query

Output

1

cpsdb=# SELECT * FROM FRAGMENT WHERE anchor_id = 4 and attributes->>'lang' like '%en%';



Code Block
titleJson Response
collapsetrue
{
 "lang": "en", 
 "price": 699, 
 "title": "The Golden Compass", 
 "authors": [
           "Philip Pullman"
 ], 
"pub_year":1995
}                                                                                                
{
 "lang": "english", 
 "price": 895, 
 "title": "Feersum Endjinn", 
 "authors": [
            "Iain M. Banks"
 ], 
"pub_year":1994
}    
            
2cpsdb=# SELECT * FROM FRAGMENT WHERE anchor_id = 4 and attributes->>'lang' ilike '%En%';


Code Block
titleJson Response
collapsetrue
{
 "lang": "en", 
 "price": 699, 
 "title": "The Golden Compass", 
 "authors": [
           "Philip Pullman"
 ], 
"pub_year":1995
}                                                                                                
{
 "lang": "English", 
 "price": 895, 
 "title": "Feersum Endjinn", 
 "authors": [
            "Iain M. Banks"
 ], 
"pub_year":1994
}              


3

#

Query

Output

1

cpsdb=# SELECT * FROM FRAGMENT WHERE anchor_id = 4 and attributes->>'title' like '%Feersum End%';

155 | /bookstore/categories[@code='01']/books[@title='Feersum Endjinn'] | {"lang": "en", "price": 895, "title": "Feersum Endjinn", "authors": ["Iain M. Banks"], "pub_year": 1994} |         4 |       154 |            5 |

2
cpsdb=# SELECT * FROM FRAGMENT WHERE anchor_id = 4 and attributes->>'lang' like '
%en%';155 | /bookstore/categories[@code='01']/books[@title='Feersum Endjinn']    | {
en';


Code Block
titleJson Response
collapsetrue
{
 "lang": "en", 
 "price":
895
 699, 
 "title":
"Feersum Endjinn
 "The Golden Compass", 
 "authors": [
"Iain M. Banks"],

           "Philip Pullman"
 ], 
"pub_year":
1994
1995
          


2.Using SIMILAR TO Regular Expression Keyword :

The only difference between like and similar to is to pattern matches the given string. It is similar to LIKE, except that it interprets the pattern using the SQL standard's definition of a regular expression

SIMILAR TO supports these pattern-matching metacharacters borrowed from POSIX regular expressions:

  • | denotes alternation (either of two alternatives).

  • * denotes repetition of the previous item zero or more times.

  • + denotes repetition of the previous item one or more times.

  • ? denotes repetition of the previous item zero or one time.

  • {m} denotes repetition of the previous item exactly m times.

  • {m,} denotes repetition of the previous item m or more times.

  • {m,n} denotes repetition of the previous item at least m and not more than n times.

  • Parentheses () can be used to group items into a single logical item.

  • A bracket expression [...] specifies a character class, just as in POSIX regular expressions.

#

Query

Output

1
                                                                                      |         4 |       154 |            5 |
 156 | /bookstore/categories[@code='01']/books[@title='Far Horizons']       | {"lang": "en", "price": 1099, "title": "Far Horizons", "authors": ["Rober Silverberg", "Joe Haldeman", "Orson Scott Card", "Ursula K. Le Guin", "Dan Simmons", "david Brin", "Greg Bear"], "pub_year": 1999} |         4 |       154 |            5 |3
cpsdb=# SELECT * FROM FRAGMENT WHERE anchor_id =
4
3 and attributes->>'pub_year'
like '%99%';153 | /bookstore/categories[@code='02']/books[@title='The Golden Compass'] | {
similar to '%(94|95)%';


Code Block
titleJson Response
collapsetrue
{
 "lang": "en", 
 "price": 699, 
 "title": "The Golden Compass", 
 "authors": [
           "Philip Pullman"
 ], 
"pub_year":1995
                                                                                            
  |         4 |       152 |            5 |
 155 | /bookstore/categories[@code='01']/books[@title='Feersum Endjinn']    | {
  
{
 "lang": "
en
english", 
 "price": 895, 
 "title": "Feersum Endjinn", 
 "authors": [
            "Iain M. Banks"
 ], 
"pub_year":1994
}              


Performance wise : As we are not making much changes for query , the performance is similar to existing query will not effect much


Implementation of Contains Operator

1.Update antlr parser to recognize this pattern
2.Implement required (native) query
3.Add Integration tests for
   

...

 a.filter on string leaf-value
     b.filter on Integer leaf-value
4.Update documentation
5.demo to team 


Limitations

1. contains condition is case sensitive.
2. Only leaves can be used, leaf-list are not supported.
3. Only string and integer values are supported, boolean and float values are not supported.
4. When empty value is passed with contains it returns all the nodes that has given leaf element.