การจับคู่ชื่อบางส่วนในล้านเรคคอร์ด


10

เราได้พัฒนาแอพพลิเคชั่นบนเว็บสำหรับการจับคู่ชื่อ มันทำงานโดยการแบ่งชื่อออกเป็นส่วน ๆ และค่าSoundexของแต่ละส่วนจะถูกเก็บไว้ในฐานข้อมูล เมตริก Levenshtein ระยะทางที่ใช้ในการสมัครเปอร์เซ็นต์การจับคู่ของเสียงเช่นเดียวกับการสะกดคำกับชื่อที่กำหนด

ที่รันไทม์เราโหลดเร็กคอร์ดทั้งหมดลงในหน่วยความจำและใช้ระยะทาง Levenshtein กับค่า Soundex ทั้งหมดและการสะกดคำของส่วนทั้งหมดของชื่อทั้งหมด

สิ่งนี้ใช้ได้ดีในตอนแรกเพราะมีชื่อสูงสุด 20,000 ชื่อ แต่ตอนนี้ลูกค้าของเรารายหนึ่งมีชื่อ 30 ล้านชื่อ การโหลดรายการขนาดใหญ่นี้ลงในหน่วยความจำสำหรับคำขอแต่ละครั้งและการใช้การจับคู่ประเภทนี้เป็นวิธีที่น่าสมเพชโดยใช้หน่วยความจำและเวลาดำเนินการจำนวนมาก

เรากำลังมองหาคำแนะนำในการค้นหาฐานข้อมูล 30 ล้านรายการขึ้นไปในอนาคตอันใกล้นี้ด้วยการจับคู่เปอร์เซ็นต์ของเสียงและการสะกดคำ

ฟังก์ชั่นหลัก

ผู้ใช้ปลายทางป้อนชื่อที่จะจับคู่และเปอร์เซ็นต์ขั้นต่ำ เราควรจะแสดงชื่อเหล่านั้นทั้งหมดในฐานข้อมูลที่ส่วนใดส่วนหนึ่งของชื่อตรงกับส่วนใดส่วนหนึ่งของชื่อที่กำหนดจนถึงเปอร์เซ็นต์ที่กำหนด ไม่จำเป็นต้องใช้ชื่อเต็มในการจับคู่ส่วนใดส่วนหนึ่งหากตรงกันไม่เกินเปอร์เซ็นต์ก็จะสำเร็จ ตัวอย่างเช่น.

Given Name: Helen Hunt
Name in DB: Holly Hunter 

ทั้งสองส่วนของชื่อทั้งสองไม่ตรงกันอย่างแน่นอน แต่ไม่เกินขอบเขตให้เราสมมติ 80% ดังนั้นหากผู้ใช้ป้อน 80% ดังนั้นชื่อใน DB จะต้องแสดงเป็นชื่อที่ตรงกัน


1
คุณใช้ SQL Server หรือไม่ ฉันเห็นคุณติดแท็กมัน asp.net คิดถึงความเป็นไปได้ของแอสเซมบลี CLR ซึ่งจะป้องกันการรับส่งข้อมูลเครือข่ายและให้เซิร์ฟเวอร์ SQL จัดการหน่วยความจำ
RubberChickenLeader

@WindRaven เราใช้ทั้ง SQL Server และ Oracle
bjan

1
นี่เป็นปัญหาการรวบรวมข้อมูลเว็บเดียวกับที่ Google แก้ไขใช่หรือไม่
candied_orange

@bjan มีการจัดเก็บชื่อไว้ที่ไหน จัดเก็บไว้ใน SQL Server หรือไม่
RubberChickenLeader

คุณกำลังหาอะไรอยู่? ชื่อ 100 อันดับแรกที่ตรงกับข้อความค้นหาที่ระบุดีที่สุด
Doc Brown

คำตอบ:


6

คุณอาจต้องการทำสิ่งใดสิ่งหนึ่งต่อไปนี้โดยไม่ทราบรายละเอียดทั้งหมดเกี่ยวกับสิ่งที่คุณต้องการ

ฉันไม่รู้ว่ามีอะไรเกี่ยวข้องกับการติดตั้งและกำหนดค่าสฟิงซ์ แต่ฉันอยู่ภายใต้การแสดงผลที่คุณสามารถชี้ไปที่ฐานข้อมูลบอกฟิลด์ที่จะจัดทำดัชนีวิธีคำนวณน้ำหนักผลลัพธ์และจะให้รายการเรียงลำดับที่ตรงกันของระเบียนกลับคืน

สำหรับสิ่งที่ผู้ใช้เผชิญหรือภารกิจสำคัญให้ใช้เครื่องมือค้นหาที่มีอยู่

หากคุณเป็นเพียงนักวิชาการ ... เล่นกับ ngrams:

ตารางค้นหา ngrams สามารถใช้เป็นชุดเริ่มต้นของการจับคู่ที่เป็นไปได้และคุณสามารถใช้ Levenshtein ระยะทางในการตัดและเรียงลำดับผลลัพธ์

สมมติว่าคุณต้องการค้นหาpeopleคุณอาจทำสิ่งที่ชอบ:

_ people _________
personId: int
name: varchar
soundex_name: varchar

_ people_ngrams __
personId: int
ngramId: int

_ ngrams _________
ngramId: int
ngram: char(3)
count: int

คุณสามารถสร้าง ngrams ของคุณเป็นระยะหรือสร้างได้ทันที ทั้งสองวิธีอัลกอริธึมการค้นหาที่ง่ายและไร้เดียงสาสามารถเป็นดังนี้

search_ngrams = ngrammify(soundex(search_string));

notable_ngrams = select top 10 *
  from ngrams
  where ngram in (search_ngrams)
  order by count asc;

possible_matches = select top 1000 distinct people.*
  from people_ngrams, people
  where ngramId in (notable_ngrams);

best_matches = top 100 possible_matches
  ordered by Levenshtein_distance(match, soundex(search_string));

การใช้บางสิ่งที่คล้ายคลึงกับสิ่งนี้ (แต่ด้วยการปรับจูน "ความนิยม", บัญชีดำ, บัญชีขาว, ฯลฯ ) ฉันเห็นว่าอัลกอริทึมแบบนี้ผสานการบันทึกระหว่างชุดข้อมูลเป็นจำนวนมากรวมทั้งอำนวยความสะดวกในการค้นหาแบบกำหนดเอง สาธารณูปโภคและความพยายามในการยกเลิกการทำซ้ำบันทึกอย่างต่อเนื่อง

ตอนนี้ในกรณีของฉันฉันไม่ได้จับคู่หลายล้านระเบียนฉันกำลังมองหาการผสานที่ดีที่สุดที่เป็นไปได้ระหว่างชุดข้อมูลสองชุดตามลำดับของระเบียนนับแสนรายการ และเราต้องการให้มันทำงานได้อย่างรวดเร็ว - ภายในไม่กี่นาที (ด่วน 100,000 * 100,000 คืออะไร) และเราก็ประสบความสำเร็จ

ดังนั้นด้วยการปรับจูนอย่างถูกต้องสิ่งต่าง ๆ นี้จะเร็วและมีประสิทธิภาพ ในที่สุดเราก็สามารถผลิตชุดผสานบนเครื่องดูอัลคอร์ที่ดูล้าสมัยในเวลาไม่กี่นาทีด้วยการผสาน "ที่น่าสงสัย" โดยอัตโนมัติเพื่อการตรวจสอบด้วยตนเอง แต่มันใช้เวลามากในการค้นหาความนิยม / ความเกี่ยวข้องของ ngram และจุดเริ่มต้นของสตริงที่ถูกต้องและบัญชีดำและบัญชีขาว ... ฯลฯ

นั่นคุณสามารถดูดเข้าไปในหลุมที่ทำงานกับสิ่งนี้ได้ สำหรับสิ่งของระดับการผลิตใด ๆ ในโลกแห่งความเป็นจริงโดยทั่วไปคุณควรใช้เครื่องมือที่ได้รับการยอมรับอย่างดีซึ่งได้สร้างและปรับให้เหมาะสมสำหรับการค้นหาประเภทนี้

เช่นเดียวกับสฟิงซ์หรือLucene


ฉันเพิ่งค้นหาคลุมเครือในคู่มืออ้างอิงสฟิงซ์ 2.2.11และดูเหมือนว่าจะตรงกับคำที่แน่นอนในขณะที่ฉันต้องจับคู่คำบางส่วน แก้ไขฉันหากฉันผิดเกี่ยวกับเรื่องนี้
bjan

@bjan Yeah เมื่อมองดูเอกสารเพิ่มเติมฉันไม่แน่ใจว่าการค้นหาคลุมเครือของสฟิงซ์เป็นสิ่งที่คุณต้องการอย่างแน่นอน มันสามารถใช้ลักษณะทางสัณฐานวิทยา Soundex แต่จากการแก้ไขล่าสุดของคุณคุณอาจต้องการค้นหา ngram + string-distance ของคุณเอง และอย่างที่ฉันได้กล่าวไว้ข้างต้นอาจต้องใช้เวลาสักครู่ในการปรับแต่งอัลกอริธึมและขีด จำกัด เพื่อให้ถูกต้อง แต่มันเป็นไปไม่ได้ และถ้าคุณจะต้องเป็นระดับที่มีความยืดหยุ่น ...
svidgen

@bjan โอ้ฉันยังลืมเรื่องทั้งหมดLucene ฉันไม่แน่ใจว่ามันเป็นสิ่งที่คุณต้องการอย่างใดอย่างหนึ่ง; แต่มันก็ค่อนข้างได้รับความนิยมและคุ้มค่าที่จะดูก่อนที่คุณจะม้วนเอง เอกสารของ Luceneพูดถึงการค้นหาและการจัดอันดับที่ไม่ชัดโดยใช้ Levenshtein string distance
svidgen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.