ตัดกันการค้นหา:ชุดผลการค้นหาด้วย cts:ชุดผลการค้นหาที่ใช้ cts:การค้นหาภูมิสารสนเทศรูปหลายเหลี่ยม

ฉันต้องเพิ่มความสามารถในการค้นหาเชิงพื้นที่ให้กับแอปที่มีอยู่แล้วซึ่งใช้ search:search API และมีการค้นหาข้อความแบบเต็มและการค้นหาแบบ faceted ฉันได้อ่านเกี่ยวกับการขยาย Search API แล้ว แต่ตอนนี้ฉันไม่มีเวลา ดังนั้น ฉันคิดว่าฉันจะปรับโค้ดของฉันเพื่อที่จะทำการตัดกันของชุดผลลัพธ์ทั้งสองชุด (ชุดหนึ่งส่งคืนโดย search:search API และอีกชุดส่งคืนโดย cts:search ที่อนุญาตการค้นหา cts:polygon) น่าเสียดายที่ทางแยกทำให้เวลาในการดำเนินการลดลงอย่างมาก มีวิธีที่ดีกว่าในการเพิ่มประสิทธิภาพหรือเร่งความเร็วนิพจน์ต่อไปนี้หรือไม่?

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

นี่คือรหัสของฉัน:

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 แหล่งที่มา


คำตอบ (4)


ตามเชิงอรรถสำหรับคำแนะนำที่ดีของ Dave อีกทางเลือกหนึ่งคือการใช้ search:parse() แทน search:search() เพื่อแปลงคำขอค้นหาที่สองเป็น cts:query ก่อนที่จะเรียกใช้ cts:search()

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

จากนั้น เพิ่ม cts:query() ที่สร้างการค้นหา:parse() ไปยังรายการแบบสอบถามย่อยภายใน cts:and-query() ที่มีอยู่ และดำเนินการค้นหาครั้งเดียว

ไม่ชัดเจนสำหรับฉันว่าส่วนคำสั่ง cts:word-query("*") ภายในแบบสอบถามเชิงพื้นที่กำลังทำอะไรอยู่ แต่นั่นไม่เกี่ยวข้องกับประเด็นหลัก

person ehennum    schedule 05.03.2015
comment
ขอบคุณพวกคุณสำหรับข้อมูลอันมีค่าของคุณ! ฉันจะพยายามอย่างเต็มที่เพื่อลองใช้แต่ละตัวเลือกที่แนะนำที่นี่ และฉันจะยอมรับคำตอบหนึ่งคำตอบในภายหลัง ทุกคำตอบมีประโยชน์ - person Lenti Pacurar; 09.03.2015

Lenti ภาคแสดง XPath ที่คุณกำลังใช้งานกำลังเปรียบเทียบทุกการค้นหา: ผลลัพธ์ Vhe กับทุกๆ $geo_results Vhe - อาจมีงานจำนวนมาก ขึ้นอยู่กับจำนวนผลลัพธ์ทางภูมิศาสตร์ที่พบ ฉันคิดว่าคุณอาจประเมินค่าสูงเกินไปว่าจะต้องใช้งานมากเพียงใดในการขยาย Search API หากคุณไปในเส้นทางนั้น MarkLogic สามารถจัดการการปรับให้เหมาะสมสำหรับคุณได้

สิ่งที่คุณต้องการคือข้อจำกัดแบบกำหนดเอง คุณจะต้องใช้ฟังก์ชันแยกวิเคราะห์เท่านั้น ไม่ใช่เริ่มต้นและสิ้นสุด (คุณต้องใช้ฟังก์ชันเหล่านี้สำหรับแง่มุมที่กำหนดเอง) ดูเหมือนว่าคุณกำลังใช้การสืบค้นแบบสตริงมากกว่าการสืบค้นแบบมีโครงสร้าง ดังนั้นสิ่งนี้:

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>/*
   :) 
};

คุณยังตั้งค่าข้อจำกัดในตัวเลือก Search API ของคุณด้วย:

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

... โดยที่ ns คือเนมสเปซที่มี "geo:" เป็นคำนำหน้าด้านบน และ at คือพาธไปยังโมดูลไลบรารีที่ฟังก์ชันการแยกวิเคราะห์ของคุณถูกกำหนดไว้

ทรัพยากร:

person Dave Cassel    schedule 05.03.2015

นอกจากคำแนะนำของ Dave และ Eriks แล้ว คุณยังสามารถทำสิ่งที่ตรงกันข้ามกับที่ Erik แนะนำได้: นำ cts:query ของ cts:search และฝังสิ่งนั้นเป็นแบบสอบถามเพิ่มเติมลงในตัวเลือกการค้นหาสำหรับ search:search คุณสามารถสร้าง $options ขึ้นมาใหม่ได้ในขณะรันไทม์ การทำเช่นนี้ช่วยให้คุณสามารถใช้ประโยชน์จากสารพัดทั้งหมดที่มีให้โดยไลบรารีการค้นหา..

ฮ!

person grtjn    schedule 05.03.2015

ต่อไปนี้เป็นแนวคิดที่ Geert และ Erik เสนอ ฉันคิดว่านี่จะช่วยลดการเปลี่ยนแปลงรหัสที่มีอยู่ให้เหลือน้อยที่สุด

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)

ฉันเห็นด้วยกับความคิดเห็นก่อนหน้านี้ว่า word-query * และ 12000 จำเป็นต้องตรวจสอบ สำหรับฉันแล้วสิ่งเหล่านี้ดูเหมือนปัญหาด้านประสิทธิภาพที่กำลังจะเกิดขึ้น

person mblakele    schedule 05.03.2015