Persimpangan pencarian: kumpulan hasil pencarian dengan cts: kumpulan hasil pencarian yang menggunakan pencarian geospasial cts:polygon

Saya harus menambahkan kemampuan pencarian geo-spasial ke aplikasi yang sudah ada yang menggunakan pencarian: API pencarian dan memiliki pencarian teks lengkap dan pencarian segi. Saya sudah membaca tentang Memperluas API Penelusuran, namun saat ini saya tidak punya waktu. Jadi, saya pikir saya akan mengadaptasi kode saya untuk melakukan perpotongan dua rangkaian hasil (satu dikembalikan oleh pencarian: API pencarian dan yang lainnya dikembalikan oleh cts:search yang memungkinkan pencarian cts:polygon). Sayangnya persimpangan tersebut sangat menurunkan waktu eksekusi. Apakah ada cara yang lebih baik untuk mengoptimalkan atau mempercepat ekspresi berikut di bawah ini?

$results_fts//search:result[./search:metadata/Vhe eq $geo_results//root/Vhe]

Ini kode saya:

declare variable $geo_results := 
let $qr := cts:search(doc(), cts:and-query(($q-geospatial,
            cts:word-query("*", ("case-insensitive","whitespace-insensitive","wildcarded","diacritic-insensitive"))   ))   )  (:Search all * within the polygon:)
return $qr;

declare variable $results_fts := 
let $qrs := search:search($q-text, $options, xs:unsignedLong(xdmp:get-request-field("start","1")), 12000)  (:max page length to get all records:)
return $qrs;

declare variable $results := 
let $qrt := if (xdmp:get-request-field("map-code")) then 
(:intersect geospatial search with the full text search:)
                <search:response>
                  { $results_fts//search:result[./search:metadata/Vhe eq $geo_results//root/Vhe] } 
                  { $results_fts//search:facet }
                  { $results_fts//search:qtext }
                  { $results_fts//search:metrics }
                </search:response>
          else $results_fts
return $qrt;

person Lenti Pacurar    schedule 05.03.2015    source sumber


Jawaban (4)


Sebagai catatan kaki untuk saran bagus Dave, alternatif lain adalah menggunakan pencarian:parse() alih-alih pencarian:pencarian() untuk mengubah permintaan pencarian kedua menjadi cts:query sebelum menjalankan cts:search().

http://docs.marklogic.com/search:parse?q=search:parse&v=8.0&api=true

Kemudian, tambahkan pencarian yang dihasilkan cts:query():parse() ke daftar subkueri dalam cts:and-query() yang ada dan jalankan satu pencarian.

Tidak jelas bagi saya apa yang dilakukan klausa cts:word-query("*") dalam kueri geospasial, tapi itu tidak ada hubungannya dengan poin utama.

person ehennum    schedule 05.03.2015
comment
Terima kasih teman-teman atas masukan berharga Anda! Saya akan melakukan yang terbaik untuk mencoba setiap opsi yang disarankan di sini dan nanti saya akan menerima salah satu jawabannya. Semua jawaban bermanfaat. - person Lenti Pacurar; 09.03.2015

Lenti, predikat XPath yang Anda jalankan membandingkan setiap search:result Vhe dengan setiap $geo_results Vhe -- berpotensi banyak pekerjaan, bergantung pada berapa banyak hasil geo yang ditemukan. Saya pikir Anda mungkin melebih-lebihkan berapa banyak pekerjaan yang diperlukan untuk memperluas Search API. Jika Anda memilih rute itu, MarkLogic dapat menangani pengoptimalan untuk Anda.

Yang Anda butuhkan adalah batasan khusus. Anda hanya perlu mengimplementasikan fungsi parse, bukan memulai dan menyelesaikan (Anda memerlukannya untuk faset khusus). Sepertinya Anda menggunakan kueri string daripada kueri terstruktur, jadi kira-kira seperti ini:

declare function geo:parse(
  $constraint-qtext as xs:string, 
  $right as schema-element(cts:query))
as schema-element(cts:query)
{
  (: TODO: you don't show above how you construct the geospatial query,
   : but do that here using $right//cts:text as input. 
   :)
  (: If MarkLogic complains that your geospatial query doesn't match
   : the return type, you probably need to serialize it like this: 
       return <root>{$q-geospatial}</root>/*
   :) 
};

Anda juga menyiapkan batasan dalam opsi Search API Anda:

<constraint name="my-custom">
  <custom facet="false">
   <parse apply="parse" ns="..." at="..." />
  </custom>
</constraint>

... di mana ns adalah namespace dengan "geo:" sebagai awalan di atasnya, dan at adalah jalur ke modul perpustakaan tempat fungsi parse Anda ditentukan.

Sumber daya:

person Dave Cassel    schedule 05.03.2015

Dan selain saran Dave dan Erik, Anda juga dapat melakukan kebalikan dari apa yang disarankan Erik: ambil cts:query dari cts:search, dan sematkan itu sebagai kueri tambahan ke dalam opsi pencarian untuk pencarian:pencarian. Anda dapat membuat ulang $options saat run-time untuk itu. Melakukannya dengan cara ini memungkinkan Anda memanfaatkan semua barang yang disediakan oleh perpustakaan pencarian..

HTH!

person grtjn    schedule 05.03.2015

Inilah perubahan ide yang diajukan Geert dan Erik. Saya pikir ini meminimalkan perubahan pada kode Anda yang ada.

declare variable $Q-GEO :=
  cts:and-query(
    ($q-geospatial,
     (: TODO This smells funny. :)
     cts:word-query(
       "*",
       ("case-insensitive", "whitespace-insensitive", "wildcarded",
        "diacritic-insensitive")) )) ;

declare variable $Q-FT := cts:query(search:parse($q-text, $options)) ;

search:resolve(
  document { cts:and-query(($Q-GEO, $Q-FT)) }/*,
  $options,
  xs:unsignedLong(xdmp:get-request-field("start", "1")),
  (: TODO Rarely a good idea to fetch so many records :)
  12000)

Saya setuju dengan komentar sebelumnya bahwa word-query * dan 12000 perlu ditinjau. Bagi saya, hal itu tampak seperti masalah kinerja yang menunggu untuk terjadi.

person mblakele    schedule 05.03.2015