ง่ายจริงๆ ใน SQL ถ้าฉันต้องการค้นหาช่องข้อความสำหรับอักขระสองสามตัวฉันสามารถทำได้:
SELECT blah FROM blah WHERE blah LIKE '%text%'
เอกสารสำหรับ App Engine ไม่ได้กล่าวถึงวิธีการบรรลุเป้าหมายนี้ แต่เป็นปัญหาที่พบบ่อยเพียงพอหรือไม่?
ง่ายจริงๆ ใน SQL ถ้าฉันต้องการค้นหาช่องข้อความสำหรับอักขระสองสามตัวฉันสามารถทำได้:
SELECT blah FROM blah WHERE blah LIKE '%text%'
เอกสารสำหรับ App Engine ไม่ได้กล่าวถึงวิธีการบรรลุเป้าหมายนี้ แต่เป็นปัญหาที่พบบ่อยเพียงพอหรือไม่?
คำตอบ:
BigTable ซึ่งเป็นแบ็คเอนด์ฐานข้อมูลสำหรับ App Engine จะปรับขนาดเป็นหลายล้านระเบียน ด้วยเหตุนี้ App Engine จึงไม่อนุญาตให้คุณทำการสืบค้นใด ๆ ที่จะส่งผลให้เกิดการสแกนตารางเนื่องจากประสิทธิภาพจะไม่ดีสำหรับตารางที่มีการเติมข้อมูลอย่างดี
กล่าวอีกนัยหนึ่งแบบสอบถามทุกรายการต้องใช้ดัชนี นี่คือเหตุผลที่คุณสามารถทำ=
, >
และ<
คำสั่ง (ในความเป็นจริงคุณสามารถทำได้เช่นกัน!=
แต่ API ทำสิ่งนี้โดยใช้การรวมกันของ>
และ<
แบบสอบถาม) นี่คือสาเหตุที่สภาพแวดล้อมการพัฒนาตรวจสอบคำค้นหาทั้งหมดที่คุณทำและเพิ่มดัชนีที่ขาดหายไปในindex.yaml
ไฟล์ของคุณโดยอัตโนมัติ
ไม่มีวิธีจัดทำดัชนีสำหรับLIKE
แบบสอบถามจึงไม่สามารถใช้ได้
ดูเซสชัน Google IO นี้เพื่อรับคำอธิบายที่ดีขึ้นและละเอียดขึ้น
ฉันกำลังประสบปัญหาเดียวกัน แต่ฉันพบบางอย่างในหน้าแอพ google app:
เคล็ดลับ: ตัวกรองการค้นหาไม่มีวิธีที่ชัดเจนในการจับคู่เพียงบางส่วนของค่าสตริง แต่คุณสามารถปลอมการจับคู่คำนำหน้าโดยใช้ตัวกรองอสมการ:
db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
"abc",
u"abc" + u"\ufffd")
สิ่งนี้ตรงกับเอนทิตี MyModel ทุกตัวที่มีสตริงคุณสมบัติ prop ที่ขึ้นต้นด้วยอักขระ abc สตริง Unicode u "\ ufffd" แสดงถึงอักขระ Unicode ที่ใหญ่ที่สุดเท่าที่จะเป็นไปได้ เมื่อค่าคุณสมบัติถูกจัดเรียงในดัชนีค่าที่อยู่ในช่วงนี้คือค่าทั้งหมดที่ขึ้นต้นด้วยคำนำหน้าที่กำหนด
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html
บางทีนี่อาจทำเคล็ดลับ;)
Altough App Engine ไม่สนับสนุนคำสั่งเหมือนได้ดูที่คุณสมบัติที่ListPropertyและStringListProperty เมื่อทำการทดสอบความเท่าเทียมกันกับคุณสมบัติเหล่านี้การทดสอบจะถูกนำไปใช้กับสมาชิกรายชื่อทั้งหมดเช่นlist_property = value
ทดสอบว่าค่านั้นปรากฏที่ใดในรายการหรือไม่
บางครั้งคุณลักษณะนี้อาจใช้เป็นวิธีแก้ปัญหาเมื่อไม่มีข้อความค้นหา LIKE ตัวอย่างเช่นทำให้สามารถค้นหาข้อความอย่างง่ายตามที่อธิบายไว้ในโพสต์นี้
คุณจำเป็นต้องใช้บริการค้นหาเพื่อดำเนินการค้นหาข้อความเต็มคล้ายกับ LIKE
SQL
Gaelykให้ภาษาเฉพาะโดเมนในการดำเนินการมากขึ้นใช้งานง่ายคำค้นหา ตัวอย่างเช่นตัวอย่างต่อไปนี้จะพบหนังสือสิบเล่มแรกที่เรียงลำดับจากเล่มล่าสุดที่มีชื่อเรื่องfern
และประเภทที่ตรงกันทั้งหมดthriller
:
def documents = search.search {
select all from books
sort desc by published, SearchApiLimits.MINIMUM_DATE_VALUE
where title =~ 'fern'
and genre = 'thriller'
limit 10
}
=~
เช่นเดียวกับที่เขียนเป็นผู้ประกอบการจับคู่ของ Groovy รองรับฟังก์ชันต่างๆเช่นdistance(geopoint(lat, lon), location)
กัน
App Engine เปิดตัวบริการค้นหาข้อความเต็มวัตถุประสงค์ทั่วไปในเวอร์ชัน 1.7.0 ที่รองรับพื้นที่เก็บข้อมูล
รายละเอียดในประกาศ .
ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้งาน: https://cloud.google.com/appengine/training/fts_intro/lesson2
ดู Objectify ที่นี่ซึ่งเป็นเหมือน API การเข้าถึง Datastore มีคำถามที่พบบ่อยเกี่ยวกับคำถามนี้โดยเฉพาะนี่คือคำตอบ
ฉันจะทำแบบสอบถาม like ได้อย่างไร (เช่น "foo%")
คุณสามารถทำบางอย่างเช่น startWith หรือ endWith ถ้าคุณย้อนกลับลำดับเมื่อจัดเก็บและค้นหา คุณทำการสืบค้นช่วงที่มีค่าเริ่มต้นที่คุณต้องการและค่าที่อยู่เหนือค่าที่คุณต้องการ
String start = "foo";
... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
เพียงทำตามที่นี่: init.py # 354 "> http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search/ init .py # 354
มันได้ผล!
class Article(search.SearchableModel):
text = db.TextProperty()
...
article = Article(text=...)
article.save()
To search the full text index, use the SearchableModel.all() method to get an
instance of SearchableModel.Query, which subclasses db.Query. Use its search()
method to provide a search query, in addition to any other filters or sort
orders, e.g.:
query = article.all().search('a search query').filter(...).order(...)
ฉันทดสอบสิ่งนี้ด้วย Java API ระดับต่ำของ GAE Datastore ฉันและทำงานได้อย่างสมบูรณ์
Query q = new Query(Directorio.class.getSimpleName());
Filter filterNombreGreater = new FilterPredicate("nombre", FilterOperator.GREATER_THAN_OR_EQUAL, query);
Filter filterNombreLess = new FilterPredicate("nombre", FilterOperator.LESS_THAN, query+"\uFFFD");
Filter filterNombre = CompositeFilterOperator.and(filterNombreGreater, filterNombreLess);
q.setFilter(filter);
โดยทั่วไปแม้ว่านี่จะเป็นโพสต์เก่า แต่วิธีการสร้าง 'LIKE' หรือ 'ILIKE' คือการรวบรวมผลลัพธ์ทั้งหมดจากแบบสอบถาม '> =' จากนั้นวนซ้ำผลลัพธ์ใน python (หรือ Java) สำหรับองค์ประกอบที่มีสิ่งที่คุณ กำลังมองหา
สมมติว่าคุณต้องการกรองผู้ใช้ที่ได้รับ aq = 'luigi'
users = []
qry = self.user_model.query(ndb.OR(self.user_model.name >= q.lower(),self.user_model.email >= q.lower(),self.user_model.username >= q.lower()))
for _qry in qry:
if q.lower() in _qry.name.lower() or q.lower() in _qry.email.lower() or q.lower() in _qry.username.lower():
users.append(_qry)
เป็นไปไม่ได้ที่จะทำการค้นหา LIKE บนเครื่องมือแอป datastore การสร้าง Arraylist จะทำอย่างไรหากคุณต้องการค้นหาคำในสตริง
@Index
public ArrayList<String> searchName;
จากนั้นค้นหาในดัชนีโดยใช้ objectify
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
และสิ่งนี้จะให้รายการที่มีรายการทั้งหมดที่มีโลกที่คุณค้นหา
หากLIKE '%text%'
เปรียบเทียบกับคำหรือสองสามคำเสมอ (คิดว่าการเรียงสับเปลี่ยน) และข้อมูลของคุณเปลี่ยนแปลงอย่างช้าๆ (อย่างช้าๆหมายความว่ามันไม่แพงเกินห้ามใจ - ทั้งราคาที่ชาญฉลาดและประสิทธิภาพที่ชาญฉลาดในการสร้างและอัปเดตดัชนี) จากนั้น Relation Index Entity (RIE) อาจเป็นคำตอบ
ใช่คุณจะต้องสร้างเอนทิตีที่เก็บข้อมูลเพิ่มเติมและเติมข้อมูลให้เหมาะสม ใช่มีข้อ จำกัด บางอย่างที่คุณจะต้องเล่น (ข้อ จำกัด หนึ่งคือ 5000 สำหรับความยาวของคุณสมบัติรายการในที่เก็บข้อมูล GAE) แต่การค้นหาที่ได้นั้นรวดเร็วปานสายฟ้าแลบ
สำหรับรายละเอียดโปรดดูRIEของฉันด้วย Java และ OjbectifyและRIE พร้อมโพสต์Python