Merge pull request #382 from EricBorczuk/mongo-search-workload

Add basic mongo search workload
This commit is contained in:
Jonathan Shook 2021-11-16 12:53:10 -06:00 committed by GitHub
commit cda5218aa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 266 additions and 0 deletions

View File

@ -0,0 +1,66 @@
---
title: MongoDB Search Basic
weight: 2
---
## Description
The MongoDB Search Basic workflow targets MongoDB using generated documents. Specifically, it looks to benchmark basic search cases, using the filters that are supported by the underlying data store.
By default, the documents used share the same structure and are approximately half a kilobyte in size each:
* Each document has 15 leaf values, with a maximum depth of 3
* there is at least one `string`, `boolean`, `number` and `null` leaf
* there is one array with `double` values and one with `string` values
* there is one empty array and one empty map
The example JSON looks like:
```json
{
"user_id":"56fd76f6-081d-401a-85eb-b1d9e5bba058",
"created_on":1476743286,
"full_name":"Andrew Daniels",
"married":true,
"address":{
"primary":{
"cc":"IO",
"city":"Okmulgee"
},
"secondary":{
}
},
"coordinates":[
64.65964627052323,
-122.35334535072856
],
"children":[
],
"friends":[
"3df498b1-9568-4584-96fd-76f6081da01a"
],
"debt":null,
"match1": 0, // or 1000
"match2": "true", // or "false"
"match3": true // or false
}
```
## Filters tested
The basic search workload can test the following `where` clauses:
- eq: `match3 EQ true`
- lt: `match1 LT 1`
- and: `match1 LT 1 AND match2 EQ "true"`
- or: `match1 LT 1 OR match2 EQ "true" or match3 EQ true`
- or-single-match: `match1 LT 1 OR match2 EQ "notamatch"`
## Workload Parameters
- `docscount` - the number of documents to write during rampup (default: `10_000_000`)
- `docpadding` - the number of fields to add to each document; useful for writing larger documents. A value of e.g. `5` would make each document have 20 leaf values, instead of 15. (default: `0`)
- `match-ratio` - a value between 0 and 1 detailing what ratio of the documents written should match the search parameters. If match-ratio is e.g. `0.1` then approximately one-tenth of the documents will have `match1`, `match2`, and `match3` values that are `0`, `"true"`, and `true`, respectively. (default: `0.01`)
- `fields` - the fields projection that you would like to use with Mongo, e.g. `{"debt": 1}`. This restricts the fields returned during benchmarking.

View File

@ -0,0 +1,200 @@
# nb -v run driver=mongodb yaml=mongodb-search-basic tags=phase:schema connection=mongodb://127.0.0.1 database=testdb
description: |
This workload emulates basic search operations for the mongoDB.
During the rampup phase, it generates documents, writes them to a collection, and then warms up the search paths.
During the main phase it performs various basic search filters and times their execution.
It's a counterpart of the Stargate's Documents API Basic Search workflow.
scenarios:
schema: run driver=mongodb tags==phase:schema threads==1 cycles==UNDEF
rampup-write: run driver=mongodb tags==phase:rampup-write cycles===TEMPLATE(docscount,10000000) docpadding=TEMPLATE(docpadding,0) match-ratio=TEMPLATE(match-ratio,0.01) threads=auto errors=timer,warn
rampup-read: run driver=mongodb tags==phase:rampup-read cycles===TEMPLATE(rampup-cycles, 10000000) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
main: run driver=mongodb tags==phase:main cycles===TEMPLATE(read-cycles,TEMPLATE(docscount,10000000)) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
main-eq: run driver=mongodb tags==phase:main,filter:eq cycles===TEMPLATE(read-cycles,TEMPLATE(docscount,10000000)) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
main-lt: run driver=mongodb tags==phase:main,filter:lt cycles===TEMPLATE(read-cycles,TEMPLATE(docscount,10000000)) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
main-and: run driver=mongodb tags==phase:main,filter:and cycles===TEMPLATE(read-cycles,TEMPLATE(docscount,10000000)) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
main-or: run driver=mongodb tags==phase:main,filter:or cycles===TEMPLATE(read-cycles,TEMPLATE(docscount,10000000)) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
main-or-single-match: run driver=mongodb tags==phase:main,filter:or-single-match cycles===TEMPLATE(read-cycles,TEMPLATE(docscount,10000000)) field-projection=TEMPLATE(fields,null) threads=<<threads:auto>> errors=timer,warn
bindings:
seq_key: Mod(<<docscount:10000000>>); ToString() -> String
random_key: Uniform(0,<<docscount:10000000>>); ToString() -> String
user_id: ToHashedUUID(); ToString() -> String
created_on: Uniform(1262304000,1577836800) -> long
full_name: FullNames()
married: ModuloToBoolean()
city: Cities()
country_code: CountryCodes()
lat: Uniform(-180d, 180d)
lng: Hash() -> long; Uniform(-180d, 180d)
friend_id: Add(-1); ToHashedUUID(); ToString() -> String
match1: Identity(); CoinFunc(<<match-ratio>>, FixedValue(0), FixedValue(1000))
match2: Identity(); CoinFunc(<<match-ratio>>, FixedValue("true"), FixedValue("false"))
additional_fields: ListSizedStepped(<<docpadding:0>>,Template("\"{}\":{}",Identity(),Identity())); ToString(); ReplaceAll('\[\"', ',\"'); ReplaceAll('\[', ''); ReplaceAll('\]', '') -> String
blocks:
- tags:
phase: schema
statements:
- dummy-insert: |
{
insert: "<<collection:search_basic>>",
documents: [ { _id: "dummyyyy" } ]
}
- drop-collection: |
{
drop: "<<collection:search_basic>>"
}
tags:
name: drop-collection
- create-collection: |
{
create: "<<collection:search_basic>>"
}
tags:
name: create-collection
- create-indexes: |
{
createIndexes: "<<collection:search_basic>>",
indexes: [
{
key: { user_id: 1 },
name: "user_id_idx",
unique: true
},
{
key: { created_on: 1 },
name: "created_on_idx"
},
{
key: { city: 1 },
name: "city_idx"
}
]
}
tags:
name: create-indexes
- name: rampup-write
tags:
phase: rampup-write
statements:
- write-document: |
{
insert: "<<collection:search_basic>>",
writeConcern: { w: "majority" },
documents: [
{
"_id": "{seq_key}",
"user_id": "{user_id}",
"created_on": {created_on},
"full_name": "{full_name}",
"married": {married},
"address": {
"primary": {
"city": "{city}",
"cc": "{country_code}"
},
"secondary": {}
},
"coordinates": [
{lat},
{lng}
],
"children": [],
"friends": [
"{friend_id}"
],
"debt": null,
"match1": {match1},
"match2": "{match2}",
"match3": {match2}
{additional_fields}
}
]
}
tags:
name: rampup-write
- name: rampup
tags:
phase: rampup-read
filter: eq
statements:
- read-document: |
{
find: "<<collection:search_basic>>",
filter: { match1: 0 }
}, <<field-projection:null>>
tags:
name: rampup-read
- name: main-eq
tags:
phase: main
filter: eq
statements:
- read-document: |
{
find: "<<collection:search_basic>>",
filter: { match3: true }
}, <<field-projection:null>>
tags:
name: read-document
- name: main-lt
tags:
phase: main
filter: lt
statements:
- read-document: |
{
find: "<<collection:search_basic>>",
filter: { match1: {$lt: 1}}
}, <<field-projection:null>>
tags:
name: read-document
- name: main-and
tags:
phase: main
filter: and
statements:
- read-document: |
{
find: "<<collection:search_basic>>",
filter: { match1: {$lt: 1}, match2: "true"}
}, <<field-projection:null>>
tags:
name: read-document
- name: main-or
tags:
phase: main
filter: or
statements:
- read-document: |
{
find: "<<collection:search_basic>>",
filter: { $or: [ {match1: {$lt: 1}}, {match3: true}]}
}, <<field-projection:null>>
tags:
name: read-document
- name: main-or-single-match
tags:
phase: main
filter: or-single-match
statements:
- read-document: |
{
find: "<<collection:search_basic>>",
filter: { $or: [ {match1: {$lt: 1}}, {match2: "notamatch"}]}
}, <<field-projection:null>>
tags:
name: read-document