added querying by children

This commit is contained in:
zadam 2020-05-23 10:36:49 +02:00
parent 4ea934509e
commit 3d12341ff1
3 changed files with 112 additions and 88 deletions

View File

@ -17,11 +17,9 @@ describe("Search", () => {
}); });
it("simple path match", async () => { it("simple path match", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.child( .child(note("Austria"))
note("Austria")
)
); );
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -32,11 +30,9 @@ describe("Search", () => {
}); });
it("only end leafs are results", async () => { it("only end leafs are results", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.child( .child(note("Austria"))
note("Austria")
)
); );
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -47,12 +43,10 @@ describe("Search", () => {
}); });
it("only end leafs are results", async () => { it("only end leafs are results", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.child( .child(note("Austria")
note("Austria") .label('capital', 'Vienna'))
.label('capital', 'Vienna')
)
); );
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -63,17 +57,13 @@ describe("Search", () => {
}); });
it("numeric label comparison", async () => { it("numeric label comparison", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.label('country', '', true) .label('country', '', true)
.child( .child(note("Austria")
note("Austria") .label('population', '8859000'))
.label('population', '8859000') .child(note("Czech Republic")
) .label('population', '10650000'))
.child(
note("Czech Republic")
.label('population', '10650000')
)
); );
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -84,21 +74,15 @@ describe("Search", () => {
}); });
it("numeric label comparison fallback to string comparison", async () => { it("numeric label comparison fallback to string comparison", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.label('country', '', true) .label('country', '', true)
.child( .child(note("Austria")
note("Austria") .label('established', '1955-07-27'))
.label('established', '1955-07-27') .child(note("Czech Republic")
) .label('established', '1993-01-01'))
.child( .child(note("Hungary")
note("Czech Republic") .label('established', '..wrong..'))
.label('established', '1993-01-01')
)
.child(
note("Hungary")
.label('established', '..wrong..')
)
); );
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -109,22 +93,16 @@ describe("Search", () => {
}); });
it("logical or", async () => { it("logical or", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.label('country', '', true) .label('country', '', true)
.child( .child(note("Austria")
note("Austria") .label('languageFamily', 'germanic'))
.label('languageFamily', 'germanic') .child(note("Czech Republic")
) .label('languageFamily', 'slavic'))
.child( .child(note("Hungary")
note("Czech Republic") .label('languageFamily', 'finnougric'))
.label('languageFamily', 'slavic') );
)
.child(
note("Hungary")
.label('languageFamily', 'finnougric')
)
);
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -135,18 +113,13 @@ describe("Search", () => {
}); });
it("fuzzy attribute search", async () => { it("fuzzy attribute search", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.label('country', '', true) .label('country', '', true)
.child( .child(note("Austria")
note("Austria") .label('languageFamily', 'germanic'))
.label('languageFamily', 'germanic') .child(note("Czech Republic")
) .label('languageFamily', 'slavic')));
.child(
note("Czech Republic")
.label('languageFamily', 'slavic')
)
);
let parsingContext = new ParsingContext({fuzzyAttributeSearch: false}); let parsingContext = new ParsingContext({fuzzyAttributeSearch: false});
@ -167,15 +140,10 @@ describe("Search", () => {
}); });
it("filter by note property", async () => { it("filter by note property", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.child( .child(note("Austria"))
note("Austria") .child(note("Czech Republic")));
)
.child(
note("Czech Republic")
)
);
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -185,19 +153,12 @@ describe("Search", () => {
}); });
it("filter by note's parent", async () => { it("filter by note's parent", async () => {
rootNote.child( rootNote
note("Europe") .child(note("Europe")
.child( .child(note("Austria"))
note("Austria") .child(note("Czech Republic")))
) .child(note("Asia")
.child( .child(note('Taiwan')));
note("Czech Republic")
)
)
.child(
note("Asia")
.child(note('Taiwan'))
);
const parsingContext = new ParsingContext(); const parsingContext = new ParsingContext();
@ -210,6 +171,26 @@ describe("Search", () => {
expect(searchResults.length).toEqual(1); expect(searchResults.length).toEqual(1);
expect(findNoteByTitle(searchResults, "Taiwan")).toBeTruthy(); expect(findNoteByTitle(searchResults, "Taiwan")).toBeTruthy();
}); });
it("filter by note's child", async () => {
rootNote
.child(note("Europe")
.child(note("Austria"))
.child(note("Czech Republic")))
.child(note("Oceania")
.child(note('Australia')));
const parsingContext = new ParsingContext();
let searchResults = await searchService.findNotesWithQuery('# note.child.title =* Aust', parsingContext);
expect(searchResults.length).toEqual(2);
expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy();
expect(findNoteByTitle(searchResults, "Oceania")).toBeTruthy();
searchResults = await searchService.findNotesWithQuery('# note.child.title =* Aust AND note.child.title *= republic', parsingContext);
expect(searchResults.length).toEqual(1);
expect(findNoteByTitle(searchResults, "Europe")).toBeTruthy();
});
}); });
/** @return {Note} */ /** @return {Note} */

View File

@ -0,0 +1,36 @@
"use strict";
const Expression = require('./expression');
const NoteSet = require('../note_set');
class ParentOfExp extends Expression {
constructor(subExpression) {
super();
this.subExpression = subExpression;
}
execute(inputNoteSet, searchContext) {
const subInputNoteSet = new NoteSet();
for (const note of inputNoteSet.notes) {
subInputNoteSet.addAll(note.children);
}
const subResNoteSet = this.subExpression.execute(subInputNoteSet, searchContext);
const resNoteSet = new NoteSet();
for (const childNote of subResNoteSet.notes) {
for (const parentNote of childNote.parents) {
if (inputNoteSet.hasNote(parentNote)) {
resNoteSet.add(parentNote);
}
}
}
return resNoteSet;
}
}
module.exports = ParentOfExp;

View File

@ -4,6 +4,7 @@ const AndExp = require('./expressions/and');
const OrExp = require('./expressions/or'); const OrExp = require('./expressions/or');
const NotExp = require('./expressions/not'); const NotExp = require('./expressions/not');
const ChildOfExp = require('./expressions/child_of'); const ChildOfExp = require('./expressions/child_of');
const ParentOfExp = require('./expressions/parent_of');
const PropertyComparisonExp = require('./expressions/property_comparison'); const PropertyComparisonExp = require('./expressions/property_comparison');
const AttributeExistsExp = require('./expressions/attribute_exists'); const AttributeExistsExp = require('./expressions/attribute_exists');
const LabelComparisonExp = require('./expressions/label_comparison'); const LabelComparisonExp = require('./expressions/label_comparison');
@ -56,6 +57,12 @@ function getExpression(tokens, parsingContext) {
return new ChildOfExp(parseNoteProperty()); return new ChildOfExp(parseNoteProperty());
} }
if (tokens[i] === 'child') {
i += 1;
return new ParentOfExp(parseNoteProperty());
}
if (tokens[i] === 'title') { if (tokens[i] === 'title') {
const propertyName = tokens[i]; const propertyName = tokens[i];
const operator = tokens[i + 1]; const operator = tokens[i + 1];