1- // package net.ravendb.client.test.querying;
2-
3- // import net.ravendb.client.RemoteTestBase;
4- // import net.ravendb.client.documents.IDocumentStore;
5- // import net.ravendb.client.documents.indexes.AbstractMultiMapIndexCreationTask;
6- // import net.ravendb.client.documents.indexes.FieldIndexing;
7- // import net.ravendb.client.documents.indexes.FieldStorage;
8- // import net.ravendb.client.documents.indexes.FieldTermVector;
9- // import net.ravendb.client.documents.queries.Query;
10- // import net.ravendb.client.documents.queries.highlighting.HighlightingOptions;
11- // import net.ravendb.client.documents.queries.highlighting.Highlightings;
12- // import net.ravendb.client.documents.session.IDocumentSession;
13- // import net.ravendb.client.primitives.Reference;
14- // import org.junit.jupiter.api.Test;
15-
16- // import java.util.ArrayList;
17- // import java.util.Arrays;
18- // import java.util.List;
19-
20- // public class HighlightesTest extends RemoteTestBase {
21-
22- // private interface ISearchable {
23- // String getSlug();
24- // void setSlug(String slug);
25-
26- // String getTitle();
27- // void setTitle(String title);
28-
29- // String getContent();
30- // void setContent(String content);
31- // }
32-
33- // public static class EventsItem implements ISearchable {
34- // private String id;
35- // private String title;
36- // private String slug;
37- // private String content;
38-
39- // public String getId() {
40- // return id;
41- // }
42-
43- // public void setId(String id) {
44- // this.id = id;
45- // }
46-
47- // @Override
48- // public String getTitle() {
49- // return title;
50- // }
51-
52- // @Override
53- // public void setTitle(String title) {
54- // this.title = title;
55- // }
56-
57- // @Override
58- // public String getSlug() {
59- // return slug;
60- // }
61-
62- // @Override
63- // public void setSlug(String slug) {
64- // this.slug = slug;
65- // }
66-
67- // @Override
68- // public String getContent() {
69- // return content;
70- // }
71-
72- // @Override
73- // public void setContent(String content) {
74- // this.content = content;
75- // }
76- // }
77-
78- // public static class SearchResults {
79- // private ISearchable result;
80- // private List<String> highlights;
81- // private String title;
82-
83- // public ISearchable getResult() {
84- // return result;
85- // }
86-
87- // public void setResult(ISearchable result) {
88- // this.result = result;
89- // }
90-
91- // public List<String> getHighlights() {
92- // return highlights;
93- // }
94-
95- // public void setHighlights(List<String> highlights) {
96- // this.highlights = highlights;
97- // }
98-
99- // public String getTitle() {
100- // return title;
101- // }
102-
103- // public void setTitle(String title) {
104- // this.title = title;
105- // }
106- // }
107-
108- // public static class ContentSearchIndex extends AbstractMultiMapIndexCreationTask {
109- // public ContentSearchIndex() {
110-
111- // addMap("docs.EventsItems.Select(doc => new {\n" +
112- // " doc = doc,\n" +
113- // " slug = Id(doc).ToString().Substring(Id(doc).ToString().IndexOf('/') + 1)\n" +
114- // "}).Select(this0 => new {\n" +
115- // " slug = this0.slug,\n" +
116- // " title = this0.doc.title,\n" +
117- // " content = this0.doc.content\n" +
118- // "})");
119-
120- // index("slug", FieldIndexing.SEARCH);
121- // store("slug", FieldStorage.YES);
122- // termVector("slug", FieldTermVector.WITH_POSITIONS_AND_OFFSETS);
123-
124- // index("title", FieldIndexing.SEARCH);
125- // store("title", FieldStorage.YES);
126- // termVector("title", FieldTermVector.WITH_POSITIONS_AND_OFFSETS);
127-
128- // index("content", FieldIndexing.SEARCH);
129- // store("content", FieldStorage.YES);
130- // termVector("content", FieldTermVector.WITH_POSITIONS_AND_OFFSETS);
131- // }
132- // }
133-
134- // @Test
135- // public void searchWithHighlights() throws Exception {
136- // String q = "session";
137-
138- // try (IDocumentStore store = getDocumentStore()) {
139-
140- // try (IDocumentSession session = store.openSession()) {
141- // EventsItem eventsItem = new EventsItem();
142- // eventsItem.setSlug("ravendb-indexes-explained");
143- // eventsItem.setTitle("RavenDB indexes explained");
144- // eventsItem.setContent("Itamar Syn-Hershko: Afraid of Map/Reduce? In this session, core RavenDB developer Itamar Syn-Hershko will walk through the RavenDB indexing process, grok it and much more.");
145- // session.store(eventsItem);
146- // session.saveChanges();
147- // }
148-
149- // new ContentSearchIndex().execute(store);
150-
151- // try (IDocumentSession session = store.openSession()) {
152- // HighlightingOptions options = new HighlightingOptions();
153- // options.setPreTags(new String[] { "<span style='background: yellow'>" });
154- // options.setPostTags(new String[] { "</span>" });
155-
156- // Reference<Highlightings> titleHighlighting = new Reference<>();
157- // Reference<Highlightings> slugHighlighting = new Reference<>();
158- // Reference<Highlightings> contentHighlighting = new Reference<>();
159-
160-
161- // List<ISearchable> results = session.query(ISearchable.class, Query.index("ContentSearchIndex"))
162- // .waitForNonStaleResults()
163- // .highlight("title", 128, 2, options, titleHighlighting)
164- // .highlight("slug", 128, 2, options, slugHighlighting)
165- // .highlight("content", 128, 2, options, contentHighlighting)
166- // .search("slug", q).boost(15)
167- // .search("title", q).boost(12)
168- // .search("content", q)
169- // .toList();
170-
171- // List<SearchResults> orderedResults = new ArrayList<>();
172- // for (ISearchable searchable : results) {
173- // String docId = session.advanced().getDocumentId(searchable);
174-
175- // List<String> highlights = new ArrayList<>();
176-
177- // String title = null;
178- // String[] titles = titleHighlighting.value.getFragments(docId);
179- // if (titles.length == 1) {
180- // title = titles[0];
181- // } else {
182- // highlights.addAll(Arrays.asList(titleHighlighting.value.getFragments(docId)));
183- // }
184-
185- // highlights.addAll(Arrays.asList(slugHighlighting.value.getFragments(docId)));
186- // highlights.addAll(Arrays.asList(contentHighlighting.value.getFragments(docId)));
187-
188- // SearchResults searchResults = new SearchResults();
189- // searchResults.setResult(searchable);
190- // searchResults.setHighlights(highlights);
191- // searchResults.setTitle(title);
192- // orderedResults.add(searchResults);
193- // }
194- // }
195- // }
196- // }
197- // }
1+ import * as mocha from "mocha" ;
2+ import * as assert from "assert" ;
3+ import { User , Company , Order } from "../../Assets/Entities" ;
4+ import { assertThat } from "../../Utils/AssertExtensions" ;
5+ import { testContext , disposeTestDocumentStore } from "../../Utils/TestUtil" ;
6+
7+ import {
8+ RavenErrorType ,
9+ IDocumentStore ,
10+ AbstractMultiMapIndexCreationTask ,
11+ Highlightings ,
12+ } from "../../../src" ;
13+
14+ interface ISearchable {
15+ slug : string ;
16+ title : string ;
17+ content : string ;
18+ }
19+
20+ class EventsItem implements ISearchable {
21+ public id : string ;
22+ public title : string ;
23+ public slug : string ;
24+ public content : string ;
25+ }
26+
27+ class SearchResults {
28+ public result : ISearchable ;
29+ public highlights : string [ ] ;
30+ public title : string ;
31+ }
32+
33+ class ContentSearchIndex extends AbstractMultiMapIndexCreationTask {
34+ public constructor ( ) {
35+ super ( ) ;
36+
37+ this . addMap ( "docs.eventsItems.Select(doc => new {\n" +
38+ " doc = doc,\n" +
39+ " slug = Id(doc).ToString().Substring(Id(doc).ToString().IndexOf('/') + 1)\n" +
40+ "}).Select(this0 => new {\n" +
41+ " slug = this0.slug,\n" +
42+ " title = this0.doc.title,\n" +
43+ " content = this0.doc.content\n" +
44+ "})" ) ;
45+
46+ this . index ( "slug" , "Search" ) ;
47+ this . store ( "slug" , "Yes" ) ;
48+ this . termVector ( "slug" , "WithPositionsAndOffsets" ) ;
49+
50+ this . index ( "title" , "Search" ) ;
51+ this . store ( "title" , "Yes" ) ;
52+ this . termVector ( "title" , "WithPositionsAndOffsets" ) ;
53+
54+ this . index ( "content" , "Search" ) ;
55+ this . store ( "content" , "Yes" ) ;
56+ this . termVector ( "content" , "WithPositionsAndOffsets" ) ;
57+ }
58+ }
59+
60+ describe ( "HighlightsTest" , function ( ) {
61+
62+ let store : IDocumentStore ;
63+
64+ beforeEach ( async function ( ) {
65+ store = await testContext . getDocumentStore ( ) ;
66+ } ) ;
67+
68+ afterEach ( async ( ) =>
69+ await disposeTestDocumentStore ( store ) ) ;
70+
71+ it ( "searchWithHighlights" , async ( ) => {
72+ const q = "session" ;
73+ const eventItem = Object . assign ( new EventsItem ( ) , {
74+ slug : "ravendb-indexes-explained" ,
75+ title : "RavenDB indexes explained" ,
76+ // tslint:disable-next-line:max-line-length
77+ content : "Itamar Syn-Hershko: Afraid of Map/Reduce? In this session, core RavenDB developer Itamar Syn-Hershko will walk through the RavenDB indexing process, grok it and much more."
78+ } ) ;
79+
80+ {
81+ const session = store . openSession ( ) ;
82+ await session . store ( eventItem ) ;
83+
84+ await session . saveChanges ( ) ;
85+ }
86+
87+ const index = new ContentSearchIndex ( ) ;
88+ await index . execute ( store ) ;
89+ await testContext . waitForIndexing ( store ) ;
90+
91+ {
92+ const hightlightOpts = {
93+ fragmentLength : 128 ,
94+ fragmentCount : 2 ,
95+ preTags : [ "<span style='background: yellow'>" ] ,
96+ postTags : [ "</span>" ]
97+ } ;
98+
99+ let titleHighlighting : Highlightings ;
100+ let slugHighlighting : Highlightings ;
101+ let contentHighlighting : Highlightings ;
102+
103+ const session = store . openSession ( ) ;
104+ const results = await session . query < ISearchable > ( { indexName : index . getIndexName ( ) } )
105+ . waitForNonStaleResults ( )
106+ . highlight ( Object . assign ( { fieldName : "title" } , hightlightOpts ) , _ => titleHighlighting = _ )
107+ . highlight ( Object . assign ( { fieldName : "slug" } , hightlightOpts ) , _ => slugHighlighting = _ )
108+ . highlight ( Object . assign ( { fieldName : "content" } , hightlightOpts ) , _ => contentHighlighting = _ )
109+ . search ( "slug" , q ) . boost ( 15 )
110+ . search ( "title" , q ) . boost ( 12 )
111+ . search ( "content" , q )
112+ . all ( ) ;
113+
114+ assert . ok ( results . length ) ;
115+ assert . ok ( titleHighlighting ) ;
116+ assert . ok ( slugHighlighting ) ;
117+ assert . ok ( contentHighlighting ) ;
118+
119+ assert . strictEqual ( titleHighlighting . fieldName , "title" ) ;
120+ assert . strictEqual ( titleHighlighting . getFragments ( eventItem . id ) . length , 0 ) ;
121+
122+ assert . strictEqual ( slugHighlighting . fieldName , "slug" ) ;
123+ assert . strictEqual ( slugHighlighting . getFragments ( eventItem . id ) . length , 0 ) ;
124+
125+ assert . strictEqual ( contentHighlighting . fieldName , "content" ) ;
126+ const fragments = contentHighlighting . getFragments ( eventItem . id ) ;
127+ assert . strictEqual ( fragments . length , 1 ) ;
128+ assert . ok ( fragments [ 0 ] . indexOf ( `<span style='background: yellow'>session</span>` ) !== - 1 ) ;
129+
130+ const orderedResults = [ ] ;
131+ for ( const searchable of results ) {
132+ const docId = session . advanced . getDocumentId ( searchable ) ;
133+
134+ const highlights = [ ] ;
135+
136+ let title = null ;
137+ const titles = titleHighlighting . getFragments ( docId ) ;
138+ if ( titles . length === 1 ) {
139+ title = titles [ 0 ] ;
140+ } else {
141+ highlights . push ( ...titleHighlighting . getFragments ( docId ) ) ;
142+ }
143+
144+ highlights . push ( slugHighlighting . getFragments ( docId ) ) ;
145+ highlights . push ( contentHighlighting . getFragments ( docId ) ) ;
146+
147+ const searchResults = new SearchResults ( ) ;
148+ searchResults . result = searchable ;
149+ searchResults . highlights = highlights ;
150+ searchResults . title = title ;
151+ orderedResults . push ( searchResults ) ;
152+ }
153+ }
154+ } ) ;
155+ } ) ;
0 commit comments