Skip to content

Commit 171da8c

Browse files
committed
Implement options and add new tests
1 parent c52212f commit 171da8c

4 files changed

Lines changed: 229 additions & 133 deletions

File tree

README.md

Lines changed: 112 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,19 @@
11
# Search-Engine
22

3-
A lightweight, powerful object search engine for JavaScript with advanced query syntax
3+
A lightweight, powerful object search engine for JavaScript with advanced query syntax.
44

55
<p>
6-
<a href="https://github.com/ECRomaneli/Search-Engine/tags"><img src="https://img.shields.io/github/v/tag/ecromaneli/Search-Engine?label=version&sort=semver" alt="Version"></a>
7-
<a href="https://github.com/ECRomaneli/Search-Engine/commits/master"><img src="https://img.shields.io/github/last-commit/ecromaneli/Search-Engine" alt="Last Commit"></a>
8-
<a href="https://github.com/ECRomaneli/Search-Engine/blob/master/LICENSE"><img src="https://img.shields.io/github/license/ecromaneli/Search-Engine" alt="License"></a>
9-
<a href="https://github.com/ECRomaneli/Search-Engine/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg" alt="Contributions Welcome"></a>
6+
<a href="https://github.com/ECRomaneli/Search-Engine/tags"><img src="https://img.shields.io/github/v/tag/ecromaneli/Search-Engine?label=version&sort=semver" alt="Version"></a>
7+
<a href="https://github.com/ECRomaneli/Search-Engine/commits/master"><img src="https://img.shields.io/github/last-commit/ecromaneli/Search-Engine" alt="Last Commit"></a>
8+
<a href="https://github.com/ECRomaneli/Search-Engine/blob/master/LICENSE"><img src="https://img.shields.io/github/license/ecromaneli/Search-Engine" alt="License"></a>
9+
<a href="https://github.com/ECRomaneli/Search-Engine/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg" alt="Contributions Welcome"></a>
1010
</p>
1111

1212
## Installation
1313

1414
```bash
1515
npm install @ecromaneli/search-engine
16-
```
17-
18-
## Download
19-
20-
For browser usage, you can download and use the pre-built version:
21-
22-
1. Go to the [Releases page](https://github.com/ECRomaneli/Search-Engine/releases/latest)
23-
2. Download the `search-engine-web.zip` file
24-
3. Extract the ZIP and include the script in your HTML:
25-
26-
```html
27-
<!-- Include the script in your HTML file -->
28-
<script src="path/to/search-engine.js"></script>
29-
<!-- Or use the minified version -->
30-
<!-- <script src="path/to/search-engine.min.js"></script> -->
31-
32-
<script>
33-
// Sample data
34-
const users = [
35-
{ id: 1, name: 'John Doe', age: 28, tags: ['developer', 'javascript'] },
36-
{ id: 2, name: 'Jane Smith', age: 34, tags: ['designer', 'ui/ux'] },
37-
{ id: 3, name: 'Bob Johnson', age: 45, tags: ['manager', 'finance'] }
38-
];
39-
40-
// Use SearchEngine.search() directly
41-
const results = SearchEngine.search(users, 'name:john');
42-
console.log(results);
43-
</script>
44-
```
16+
```
4517

4618
## Features
4719

@@ -52,69 +24,149 @@ For browser usage, you can download and use the pre-built version:
5224
- Logical negation of search terms
5325
- Nested property searching
5426
- Logical grouping with parentheses
27+
- Customizable search options
5528
- Zero dependencies
5629

5730
## Basic Usage
5831

5932
```javascript
60-
const { search } = require('@ecromaneli/search-engine')
33+
const { SearchEngine } = require('@ecromaneli/search-engine')
6134

62-
// Sample data
6335
const users = [
6436
{ id: 1, name: 'John Doe', age: 28, tags: ['developer', 'javascript'] },
6537
{ id: 2, name: 'Jane Smith', age: 34, tags: ['designer', 'ui/ux'] },
6638
{ id: 3, name: 'Bob Johnson', age: 45, tags: ['manager', 'finance'] }
6739
]
6840

69-
// Simple search
70-
const result1 = search(users, '"john"') // Find users with "john" in any field
41+
const result = SearchEngine.search(users, 'name: john')
42+
console.log(result)
43+
```
7144

72-
// Field-specific search
73-
const result2 = search(users, 'name:jane') // Find users with "jane" in the name field
45+
## Using the SearchEngine Constructor
7446

75-
// Age range search
76-
const result3 = search(users, 'age~:25-35') // Find users with age between 25 and 35
47+
You can create a `SearchEngine` instance with specific options that will be used for all searches:
7748

78-
// Complex search with boolean operators and grouping
79-
const result4 = search(users, '("developer" or "designer") and not age~:40-50')
49+
```javascript
50+
const engine = new SearchEngine({
51+
excludeKeys: ['password', 'private.info'],
52+
allowNumericString: false,
53+
allowKeyValueMatching: true,
54+
matchChildKeysAsValues: false
55+
})
56+
57+
const results = engine.search(users, 'age~: 25-35')
58+
console.log(results)
8059
```
8160

61+
## Search Options
62+
63+
The `SearchOptions` object allows you to customize the behavior of the search engine. Below is a table explaining each option:
64+
65+
| Option | Type | Default | Description |
66+
|--------------------------|------------|---------|-------------------------------------------------------------------------------------------------|
67+
| `excludeKeys` | `string[]` | `[]` | Array of keys to exclude from search. Useful for excluding sensitive data. |
68+
| `allowNumericString` | `boolean` | `true` | Controls whether string values that can be parsed as numbers are used in range searches. |
69+
| `allowKeyValueMatching` | `boolean` | `true` | When enabled, unquoted terms without a field/value separator match both field names and values. |
70+
| `matchChildKeysAsValues` | `boolean` | `false` | When enabled, after finding a matching key, also looks for the value in child object keys. |
71+
72+
### Differences Between Options
73+
74+
- **`allowNumericString`**:
75+
- When `true`, strings like `"123"` will be treated as numbers in range searches.
76+
- When `false`, only actual numbers will be considered for range searches.
77+
78+
- **`allowKeyValueMatching`**:
79+
- When `true`, a query like `"admin"` will match both `{ admin: "value" }` and `{ key: "admin" }`.
80+
- When `false`, it will only match field names or values explicitly.
81+
82+
- **`matchChildKeysAsValues`**:
83+
- When `true`, a query like `"foo:bar"` will match both `{ foo: "bar" }` and `{ foo: { bar: "value" } }`.
84+
- When `false`, it will only match `{ foo: "bar" }`.
85+
8286
## Query Syntax Reference
8387

8488
### Basic Queries
8589

86-
- `field` - Search for "field" with any value
87-
- `"value"` - Search for "value" in any field
88-
- `field:value` - Search for "value" in the specific field
90+
- `foo` - Search for objects having a field or value `foo`.
91+
- `"value"` - Search for `"value"` in any field.
92+
- `field: value` - Search for `value` in the specific `field`.
8993

9094
### Specialized Searches
9195

92-
- `field*:pattern` - Regex pattern match on field
93-
- `field~:min-max` - Numeric range search (min and max are optional)
96+
- `field*: pattern` - Regex pattern match on field.
97+
- `field~: min-max` - Numeric range search.
98+
- `field~: 10-` - Numbers greater than or equal to 10.
99+
- `field~: -20` - Numbers less than or equal to 20.
100+
101+
Negative values are also supported.
94102

95103
### Boolean Operators
96104

97-
- `term1 and term2` - Both terms must match
98-
- `term1 or term2` - Either term must match
105+
- `term1 and term2` - Both terms must match.
106+
- `term1 or term2` - Either term must match.
99107

100108
### Negation and Grouping
101109

102-
- `not term` - Term must not match
103-
- `not (term1 or term2) and term3` - Logical grouping with parentheses
110+
- `not term` - Term must not match.
111+
- `not (term1 or term2)` - Group negation (neither term1 nor term2 should match).
112+
- `(term1 or term2) and term3` - Logical grouping with parentheses.
104113

105114
## API Reference
106115

107-
### search(objList, queryStr, exclude)
116+
### Static Methods
117+
118+
#### `SearchEngine.search(objList, queryStr, options)`
119+
120+
- **`objList`** (`Array`): Array of objects to search through.
121+
- **`queryStr`** (`String`): Query string following the syntax described above.
122+
- **`options`** (`Object`, optional): Search options object.
123+
- **Returns** (`Array`): Array of matching objects.
124+
125+
### Instance Methods
126+
127+
To store the options, use the constructor below:
128+
129+
#### `new SearchEngine(options)`
130+
131+
- **`options`** (`Object`, optional): Search options object (see Options table).
132+
- **Returns** (`SearchEngine`): A new `SearchEngine` instance with the specified options.
133+
134+
#### `searchInstance.search(objList, queryStr)`
135+
136+
- **`objList`** (`Array`): Array of objects to search through.
137+
- **`queryStr`** (`String`): Query string following the syntax described above.
138+
- **Returns** (`Array`): Array of matching objects with the instance's options applied.
139+
140+
## Performance Tips
141+
142+
- For large datasets, consider disabling `allowNumericString` if you don't need string-to-number conversion.
143+
- Set `matchChildKeysAsValues: false` (default) unless you specifically need to match object keys as values.
144+
- Use `excludeKeys` to skip searching in fields that are never relevant to your searches.
145+
- For repeated searches with the same options, create a `SearchEngine` instance instead of using the static method.
146+
147+
## Examples and Advanced Usage
148+
149+
For a comprehensive set of usage examples covering all search engine features, refer to our test suite:
150+
151+
[View Test Examples](test/index.test.js)
152+
153+
The test file includes examples of:
154+
- Complex nested property searching
155+
- Array item searching
156+
- Logical grouping with parentheses
157+
- De Morgan's law transformations
158+
- Complex boolean expressions
159+
- Excluded keys functionality
160+
- Range searches with various configurations
161+
- Quoted values with special characters
162+
- Edge cases and error handling
108163

109-
- **objList** (Array): Array of objects to search through
110-
- **queryStr** (String): Query string following the syntax described above
111-
- **exclude** (Array, optional): Array of property names to exclude from searching
112-
- **Returns** (Array): Array of matching objects
164+
These examples serve as excellent reference implementations when building advanced search queries.
113165

114166
## Author
115167

116-
Created by [Emerson Capuchi Romaneli](https://github.com/ECRomaneli) (@ECRomaneli).
168+
Created by Emerson Capuchi Romaneli (@ECRomaneli).
117169

118170
## License
119171

120-
This project is licensed under the [MIT License](https://github.com/ECRomaneli/Search-Engine/blob/master/LICENSE).
172+
This project is licensed under the MIT License.

0 commit comments

Comments
 (0)