5

I using marklogic's search functionality to create a search page. As of right now, I'm running an XQuery to get search results through search:search. As a bare bones example, see this code:

    xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search"
        at "/MarkLogic/appservices/search/search.xqy";

search:search('test',
     <options xmlns='http://marklogic.com/appservices/search'></options>)

This search searches all content in the database, which is fine in many cases. In other cases, I search based on collections with cts:collection-query. The collections serve as great contexts for my searches.

Now, I would like to limit my search results based on a relationship of data in a "main" document. This "main" document has all the relationships in an object model. If that object model has a reference to a document, I want that document included in the search. Essentially, the "main"/model document is the context of the search.

I was trying to brainstorm some ideas of the best way to to this. Here's what I've come up with thus far, but I was hoping someone more familiar with Marklogic (I've only been working with it for 6 months) could lead me in a good direction:

  1. Add all documents referenced in the model document to a unique collection. Then query search based on that collection. However, the collections would have to be updated as the model changed.
  2. Load the model document into my code and get a list of all the references and add them to a query by cts:document-query (or the like).
  3. Restructure my concept of a "model" somehow in my XML documents.

Thanks for any input or suggestions.

Paul
  • 449
  • 1
  • 5
  • 13
  • 1
    Ended up going with #1. #2 was about 3x slower in my database. Also, because of the vast relationship model in my XML, the code for #2 was starting to get ugly. With collections in place, I'm able to allow all developers to reuse with ease. I will most likely implement triggers in the future. – Paul Aug 21 '13 at 18:12

2 Answers2

3

I would start with (2) and see if the performance is good enough. That will depend on your use-case, but I expect it should be fine for thousands or even hundreds of thousands of references.

Be sure to use a single-term cts:document-query($list-of-references). That will be faster than cts:or-query(for $ref in $list-of-references return cts:document-query($ref)), because the index lookup can be a single pass instead of N separate lookups.

mblakele
  • 7,782
  • 27
  • 45
2

All of these ideas would work fine. Deciding which to use depends on particulars of your application such as how often the main document is changed (and are you in control of it), how hard it is to remodel your XML.

Another thing to consider is you can set a trigger on document updates which could perform the collection changes automatically.

-David Lee

DALDEI
  • 3,722
  • 13
  • 9