1
1
# Mongo-Postgres Query Converter
2
2
[ MongoDB query documents] ( https://docs.mongodb.org/manual/tutorial/query-documents/ ) are quite powerful.
3
- This brings part of that usefulsness to PostgreSQL by letting you query in a similar way.
4
- This tool converts a Mongo query to a PostgreSQL "where" clause for data stored in a jsonb field.
5
- It also has additional converters for Mongo projections which are like "select" clauses and for update queries.
6
-
7
- The goal of this is to eventually provide an adapter which lets Postgres serve as a drop in replacement for Mongo, but that is not there yet.
8
- Currently the project has many of the underlying conversions that will be required to do this.
9
- For that project, see [ pgmongo] ( https://github.com/thomas4019/pgmongo ) .
10
-
11
- ### Select Query Example 1
12
- ``` javascript
13
- { ' address.city' : ' provo' ,
14
- name: ' Thomas' ,
15
- age: { ' $gte' : ' 30' } }
16
- ```
17
- becomes the following Postgres query
18
- ``` sql
19
- (data- > ' address' - >> ' city' = ' provo' ) and (data- >> ' name' = ' Thomas' ) and (data- >> ' age' >= ' 30' )
20
- ```
3
+ This brings that usefulness to PostgreSQL by letting you query in a similar way.
4
+ This tool converts a Mongo query to a PostgreSQL ` where ` clause for data stored in a jsonb field.
5
+ It also has additional converters for Mongo projections which are like ` select ` clauses and for ` update ` queries.
21
6
22
- ### Select Query Example 2
23
- ``` javascript
24
- {
25
- $or: [ { qty: { $gt: 100 } }, { price: { $lt: 9.95 } } ]
26
- }
27
- ```
28
- becomes the following Postgres query
29
- ``` sql
30
- ((data- > ' qty' > ' 100' ::jsonb) OR (data- > ' price' < ' 9.95' ::jsonb))
31
- ```
7
+ This tool is used by [ pgmongo] ( https://github.com/thomas4019/pgmongo ) which intends to provide a drop-in replacement for MongoDB.
32
8
33
- ## Getting Started
9
+ ## Installation
34
10
35
- ``` bash
11
+ ``` sh
36
12
npm install mongo-query-to-postgres-jsonb
37
13
```
38
14
39
- ``` javascript
40
- var mongoToPostgres = require (' mongo-query-to-postgres-jsonb' )
15
+ ## Simple Usage
16
+
17
+ ``` js
18
+ var mToPsql = require (' mongo-query-to-postgres-jsonb' )
41
19
var query = { field: ' value' }
42
- var sqlQuery = mongoToPostgres (' data' , query)
43
- console .log (sqlQuery)
20
+ var sqlQuery = mToPsql (' data' , query)
44
21
```
45
22
46
- The first parameter, "data", is the name of your jsonb column in your postgres table.
47
- The second parameter is the Mongo style query.
48
- There is an optional third parameter explained in the next section.
23
+ ## API
49
24
50
- ### Projection Example
51
-
52
- ``` javascript
53
- mongoToPostgres .convertSelect (' data' , { field: 1 })
54
- ```
55
- becomes the following Postgres query
56
- ``` sql
57
- jsonb_build_object(' field' , data- > ' field' , ' _id' , data- > ' _id' )'
25
+ ``` js
26
+ var mToPsql = require (' mongo-query-to-postgres-jsonb' )
58
27
```
59
28
60
- ### Update Example
29
+ ### mToPsql(sqlField, mongoQuery, [ arrayFields ] )
61
30
31
+ #### sqlField
62
32
63
- ```javascript
64
- mongoToPostgres.convertUpdate(' data' , {
65
- $set: { active: true },
66
- $inc: { purchases: 2 }
67
- })
68
- ```
69
- becomes the following Postgres query
70
- ```sql
71
- jsonb_set(jsonb_set(data,' {active}' ,' true' ::jsonb),' {purchases}' ,to_jsonb(Cast(data->>' purchases' as numeric)+2))
72
- ```
33
+ This is the name of your jsonb column in your postgres table which holds all the data.
73
34
74
- ### Sort Example
35
+ #### mongoQuery
75
36
76
- ```javascript
77
- mongoToPostgres.convertSort(' data' , {
78
- age: -1,
79
- ' first .name ' : 1
80
- })
81
- ```
82
- becomes the following Postgres query
83
- ```sql
84
- data->' age' DESC, data->' first' ->' name' ASC
85
- ```
37
+ An object containing MongoDB [ query operators] ( https://docs.mongodb.com/manual/reference/operator/query/ ) .
38
+
39
+ #### arrayFields
40
+
41
+ This tool doesn't know which fields are arrays so you can optionally specify a list of dotted paths which should be treated as an array.
42
+
43
+ ### mToPsql.convertSelect(sqlField, projectionQuery)
44
+
45
+ #### projectionQuery
46
+
47
+ Object specifying which a subset of documents to return. Note: advanced [ projection fields] ( https://docs.mongodb.com/manual/reference/operator/projection/ ) are not yet supported.
48
+
49
+ ### mToPsql.convertUpdate(sqlField, updateQuery, [ upsert] )
50
+
51
+ #### updateQuery
52
+
53
+ Object containing [ MongoDB operations] ( https://docs.mongodb.com/manual/reference/operator/update/ ) to apply to the documents.
54
+
55
+ #### upsert
56
+
57
+ Indicate that the query is being used for upserting. This will create a safer query that works if the original document doesn't already exist.
58
+
59
+ ### mToPsql.convertSort(sqlField, sortQuery, [ forceNumericSort] )
60
+
61
+ #### sortQuery
62
+
63
+ Object containing [ desired ordering] ( https://docs.mongodb.com/manual/reference/method/cursor.sort/#sort-asc-desc )
64
+
65
+ #### forceNumericSort
66
+
67
+ Cast strings to number when sorting.
68
+
69
+ ## Examples
70
+
71
+ | Languages | MongoDB | Postgres |
72
+ | ------------| -------------------------------| ---------------------------------------------------------------------------------|
73
+ | Where | { 'address.city': 'provo' } | (data->'address'->>'city' = 'provo') |
74
+ | Where | { $or: [ { qty: { $gt: 100 } }, { price: { $lt: 9.95 } } ] } | ((data->'qty'>'100'::jsonb) OR (data->'price'<'9.95'::jsonb)) |
75
+ | Projection | { field: 1 } | jsonb_build_object('field', data->'field', '_ id', data->'_ id')' |
76
+ | Update | { $set: { active: true } } | jsonb_set(data,'{active}','true'::jsonb) |
77
+ | Update | { $inc: { purchases: 2 } } | jsonb_set(data,'{purchases}',to_jsonb(Cast(data->>'purchases' as numeric)+2)) |
78
+ | Sort | { age: -1, 'first.name': 1} | data->'age' DESC, data->'first'->'name' ASC |
86
79
87
- ## Select: Match a Field Without Specifying Array Index
80
+ ## Advanced Select: Match a Field Without Specifying Array Index
88
81
89
82
* [ Mongo Docs] ( https://docs.mongodb.org/manual/tutorial/query-documents/#match-a-field-without-specifying-array-index )
90
83
91
- You can have a document with an array of objects that you want to match when any one of the elements in the array matches.
92
- This is implemented in SQL using a subquery so it may not be the most efficient.
84
+ With MongoDB, you can search a document with a subarray of objects that you want to match when any one of the elements in the array matches.
85
+ This tools implements it in SQL using a subquery so it is not be the most efficient.
93
86
94
87
Example document.
95
- ```javascript
88
+ ``` js
96
89
{
97
90
" courses" : [{
98
- "distance": "5K"
99
- }, {
100
- "distance": "10K"
101
- }]
102
- }
91
+ " distance" : " 5K"
92
+ }, {
93
+ " distance" : " 10K"
94
+ }]
95
+ ]
103
96
` ` `
104
- Unlike Mongo, this tool doesn' t know which fields are arrays and requires you to supply a list optionally as a third parameter.
105
- Example query to match when there is a course with a distance of " 5K" .
106
- ` ` ` javascript
97
+ Example query to match:
98
+ ` ` ` js
107
99
mongoToPostgres (' data' , { ' courses.distance' : ' 5K' }, [' courses' ])
108
100
` ` `
109
101
110
102
## Supported Features
111
103
* $eq, $gt, $gte, $lt, $lte, $ne
112
- * $or , $not, $nin
113
- * [$in ](https:// docs .mongodb .org/ manual/ reference/ operator/ query/ in / # use-the-in-operator-to-match-values-in-an-array), $nin
104
+ * $or, $not, [$in](https://docs.mongodb.org/manual/reference/operator/query/in/#use-the-in-operator-to-match-values-in-an-array), $nin
114
105
* $elemMatch
115
- * [$regex](https:// docs .mongodb .com/ manual/ reference/ operator/ query/ regex/ )
116
- * [$type](https:// docs .mongodb .org/ manual/ reference/ operator/ query/ type/ # op._S_type)
117
- * [$size](https:// docs .mongodb .org/ manual/ reference/ operator/ query/ size/ # op._S_size)
118
- * [$exists](https:// docs .mongodb .org/ manual/ reference/ operator/ query/ exists/ # op._S_exists)
119
- * [$mod](https:// docs .mongodb .com/ manual/ reference/ operator/ query/ mod/ )
120
- * [$all](https:// docs .mongodb .com/ manual/ reference/ operator/ query/ all/ )
106
+ * [$regex](https://docs.mongodb.com/manual/reference/operator/query/regex/), [$type](https://docs.mongodb.org/manual/reference/operator/query/type/#op._S_type), [$size](https://docs.mongodb.org/manual/reference/operator/query/size/#op._S_size), [$exists](https://docs.mongodb.org/manual/reference/operator/query/exists/#op._S_exists), [$mod](https://docs.mongodb.com/manual/reference/operator/query/mod/), [$all](https://docs.mongodb.com/manual/reference/operator/query/all/)
121
107
122
108
## Todo
123
109
* Filtering
@@ -136,4 +122,4 @@ mongoToPostgres('data', { 'courses.distance': '5K' }, ['courses'])
136
122
* [PostgreSQL json documentation](http://www.postgresql.org/docs/9.4/static/datatype-json.html)
137
123
* [MongoDB query documention](https://docs.mongodb.org/manual/tutorial/query-documents/)
138
124
* [PostgreSQL Array Functions](https://www.postgresql.org/docs/9.3/static/functions-array.html)
139
- * [JSON array to PostgreSQL Array](https:// dba .stackexchange .com/ questions/ 54283 / how- to- turn- json- array- into- postgres- array/ 54289 # 54289)
125
+ * [JSON array to PostgreSQL Array](https://dba.stackexchange.com/questions/54283/how-to-turn-json-array-into-postgres-array/54289#54289)
0 commit comments